成员函数的声明必须在类的内部,定义则既可以在类的内部,也可以在类的外部。
作为接口组成部分的非成员函数,它们的定义和声明都在类的外部。
类可以允许其他类或者函数访问它的非公有成员,方法是令其他类或函数成为它的友元。如果类想把一个函数作为它的友元,只需要增加一条以friend关键字开始的函数声明语句即可。
友元声明只能出现在类定义的内部,但是在类内出现的具体位置不限。友元不是类的成员,不受所在区域访问控制级别的约束。一般来说,最好在类定义开始或结束前的位置集中声明友元。
如果一个类指定了友元类,声明形式friend class 类名,则友元类的成员函数可以访问此类包括非公有成员在内的所有成员。
友元关系不存在传递性。
可变数据成员,是在变量的声明中加入mutable关键字,任何成员函数,包括const成员函数,都可以修改可变数据成员的值。
含有指针数据成员的类一般不宜使用默认的拷贝和赋值操作,如果类的数据成员都是内置类型的,则直接使用类对象执行拷贝和赋值操作是可以的。
要想把类的成员函数定义成内联函数,有几种不同的途径。第一种是直接把函数定义放在类的内部,第二种是把函数定义放在类的外部,并且在定义之前显示地指定inline。
类允许包含指向它自身类型的引用或指针。
如果类的数据成员是const、引用,或者属于某种未提供默认构造函数的类类型,我们必须通过构造函数初始值列表为这些成员提供初值,示例如下:
类名(参数列表...):i(ii),ci(ii),ri(i){}
在很多类中,初始化和赋值的区别事关底层效率问题:前者直接初始化数据成员,后者则先初始化再赋值。除了效率问题外更重要的是,一些数据成员必须被初始化。
成员的初始化顺序与它们在类定义中的出现顺序一致:第一个成员先被初始化,然后第二个,以此类推。构造函数初始值列表中初始值的前后位置关系不会影响实际的初始化顺序。
如果一个构造函数为所有参数都提供了默认实参,则它实际上也定义了默认构造函数。
将构造函数声明为explicit可抑制构造函数的隐式转换。关键字explicit只对一个实参的构造函数有效,需要多个实参的构造函数不能用于执行隐式转换,所以无需将这些构造函数指定为explicit。只能在类内声明构造函数时使用explicit关键字,在类外部定义时不应加explicit关键字。
聚合类使得用户可以直接访问其成员,并且具有特殊的初始化语法形式。当一个类满足如下条件时,我们说它是聚合的:
- 所有成员都是public的
- 没有定义任何构造函数
- 没有类内初始值
- 没有基类也没有虚函数
除了静态常量成员之外,其他静态成员不能在类的内部初始化。