1.定义在类内部的函数是隐式的inline函数
2.this指针为常量指针,不允许指向其它对象
3.IO类属于不能被拷贝的类型,只能用引用来传递它们
4.合成的默认构造函数
- 若存在类内的初始值,用它来初始化成员(C++11已经支持类内初始化)
- 否则默认初始化(对于有默认构造函数的类型)
5.合成的默认构造函数注意点
- 仅当类内无声明任何构造函数
- 内置类型如int,指针这种初始化指向不明
- 若成员变量无默认构造函数则无法生成
6.参数列表后加=default则为默认构造函数
7.类成员声明为mutable,则即使在const成员函数内也可以对其进行修改
8.const成员函数可以作为成员函数重载的方式之一
相当于一个参数是*const this,一个是const * const this;
加了一个底层const,而底层const 是可以用来作为函数重载的标志的。
9.friend
- 在类内声明以friend关键字开始的函数声明语句表明该函数可以访问它的非公有成员
- friend关键字开始的类声明class A,则A的成员函数可以访问它的非公有成员,
- 也可以是类成员函数,但友元函数声明必须确保函数可见(即已声明)
- 友元的声明仅仅指定了访问权限,而非一个通常意义上的函数声明,所以需要在友元声明之外再专门对函数进行一次声明
11.构造函数初始值列表
- 如果成员是const,引用,或是未提供默认构造函数的类类型(基类,成员对象),我们必须通过构造函数初始值列表为这些成员提供初值
- 成员的初始化顺序与它们在类定义中的出现顺序一致
12.构造函数的隐式转换(只允许一步类型转换)
编译器只会自动执行一步类型转换
class A
{
public:
A(string s):str(s){}
void combine(const A &a)
{
str = srt + a.str;
}
string str;
};
//正确,编译器执行了"just test"到string的一步类型转换,然后调用了A的构造函数
A a("just test");
//错误,这里"another test"需要做两步类型自动转换(const char* → string → A)才能成为A,所以错误
a.combine("another test");
就是如果所需隐式转换的类含有单参数的构造函数,此时我们提供该单参数时才允许进行隐式转换
string s = "Test";
由于string含有常字符串的构造函数,所以"Test"可以直接转换为s
13.构造函数前加上explicit时无法完成隐式转换
- 多个参数无法实现隐式转换,所以无需explicit
- 只允许出现在类内声明构造函数处,以便阻止隐式转换
14.类内的静态成员除非是constexpr int常量成员,否则不能在类内初始化
类外的必须给出静态成员的初始值(此时static标识符不能再出现)
class Test{
public:
static int i;
};
int Test::i = 0;
15.类的声明
- 类在声明之后,定义之前是一个不完全类型
- 所以一个类的成员类型不能是该类自己,因为此时编译器不知道该类需要多少空间
- 但一个类可以包含指向自身类型的引用或指针
16.委托构造函数(delegating constructor)
C++11扩展了构造函数的初始值的功能,使得我们可以定义所谓的委托构造函数。一个委托构造函数使用它所属类的其他构造函数执行它自己的初始化过程,或者说它把它自己的一些职责委托给了其他构造函数。