第七章 类(下)
-
clear需要访问Screen的私有成员;而要想令这种访问合法,Screen需要把 window mgr 指定成它的友元
-
如果一个类指定了友元类,则友元类的成员函数可以访问此类包括非公有成员在内的所有成员
-
每个类负责控制自己的友元类或友元函数。
-
除了令整个 window mgr作为友元之外,Screen还可以只为clear 提供访问权限当把一个成员函数声明成友元时,我们必须明确指出该成员函数属于哪个类
-
Extern 用法
- 类就是一个作用域的事实能够很好地解释为什么当我们在类的外部定义成员函数时必须同时提供类名和函数名(参见7.1.2节,第230页)。在类的外部,成员的名字被隐藏起来了。
-
另一方面,函数的返回类型通常出现在函数名之前。因此当成员函数定义在类的外部时,返回类型中使用的名字都位于类的作用域之外。
-
编译器处理完类中的全部声明后才会处理成员函数的定义
-
一般来说,内层作用域可以重新定义外层作用域中的名字,即使该名字已s经在内层作用域中使用过。然而在类中,如果成员使用了外层作用域中的某个名字,而该名字代表种类型,则类不能在之后重新定义该名字
-
尽管类的成员被隐藏了,但我们仍然可以通过加上类的名字或显式地使用this指针来强制访问成员
-
不要把成员名字作为参数或其他局部变量使用
-
如果成员是const、引用,或者属于某种未提供默认构造函数的类类型,我们必须通过构造函数初始值列表为这些成员提供初值。
-
构造函数初始值列表中初始值的前后位置关系不会影响实际的初始化顺序。
-
最好令构造函数初始值的顺序与成员声明的顺序保持一致。而且如果可能的话,尽量避免使用某些成员初始化其他成员。
-
我们不提供实参也能调用上述的构造函数,所以该构造函数实际上为我们的类提供了默认构造函数。
-
和其他构造函数一样,一个委托构造函数也有一个成员初始值的列表和一个函数体。在委托构造函数内,成员初始值列表只有一个唯一的入口,就是类名本身。和其他成员初始值一样,类名后面紧跟圆括号括起来的参数列表,参数列表必须与类中另外一个构造函数匹配。
-
当一个构造函数委托给另一个构造函数时,受委托的构造函数的初始值列表和函数体被依次执行。
-
关键字 explicit 只对一个实参的构造函数有效。需要多个实参的构造函数不能用于执行隐式转换,所以无须将这些构造函数指定为explicit的。只能在类内声明构造函数时使用explicit 关键字,在类外部定义时不应重复
-
当我们用 explicit 关键字声明构造函数时,它将只能以直接初始化的形式使用
-
static cast可以使用explicit 的构造函数
-
接受一个单参数的 const char*的string构造函数(参见3.2.1节,第76页)不是explicit 的。
接受一个容量参数的vector构造函数(参见3.3.1节,第87页)是explicit的 -
聚合类初始值的顺序必须与声明的顺序一致
-
与初始化数组元素的规则(参见3.5.1节,第101页)一样,如果初始值列表中的元素个数少于类的成员数量,则靠后的成员被值初始化(参见3.5.1节,第101页)。
-
在6.5.2节(第214页)中我们提到过 constexpr 函数的参数和返回值必须是字面值类型。除了算术类型、引用和指针外,某些类也是字面值类型。和其他类不同,字面值类型的类可能含有constexpr函数成员。这样的成员必须符合constexpr函数的所有要求,它们是隐式const的(参见7.1.2节,第231页)。
-
constexpr构造函数必须初始化所有数据成员,初始值或者使用constexpr构造函数或者是一条常量表达式。
-
静态成员函数由于不与具体对象关联,没有 this 指针,因此有一些使用上的限制:不能声明为 const,也不能访问或调用非静态成员
-
和其他的成员函数一样,我们既可以在类的内部也可以在类的外部定义静态成员函数。当在类的外部定义静态成员时,不能重复static关键字,该关键字只出现在类内部的声明语句
-
必须在类的外部定义和初始化每个静态成员。和其他对象一样,一个静态数据成员只能定义一次。
-
类似于全局变量(参见6.11节,第184页),静态数据成员定义在任何函数之外。因此一旦它被定义,就将一直存在于程序的整个生命周期中。
-
即使一个常量静态数据成员在类内部被初始化了,通常情况下也应该在类的外部定义一下该成员。
第七章习题
-
显示内联和隐式内联
-
一个不完全类型。我们可以定义指向不完全类型的指针,但是无法创建不完全类型的对象
-
聚合类必须满足一些非常苛刻的条件,其中一项就是没有类内初始值
-
除了静态常量成员之外,其他静态成员不能在类的内部初始化