目录
一.P214 constexpr函数
constexpr修饰的函数,可以用于常量表达式,其返回值是一个右值。
constexpr函数需满足如下要求:
1.函数形参类型、返回类型必须是字面值类型。
字面值类型:内置类型、引用、指针类型。
2.函数体中只能有一条return语句,不能有其他语句。
例:
constexpr int func(int i) {
return 2 * i;
}
int j = 4;
int a[func(2)];//正确
int b[func(j)];//错误
编译器会对constexpr返回值进行检查,看是否是常量表达式。
比如上例func(2)返回值是 2*2即常量表达式,而func(j)的返回值是 2*j并非常量表达式。
二.P235 构造函数(const)
如果将一个类对象声明为const,那么只有在构造函数全部执行后才能获得const属性。
因此,构造函数不能声明成const。
《C++ Primer》中说“直到构造函数完成初始化才能真正获得const属性”个人认为不够准确。
完成初始化应该指的是完成初始化列表,构造函数内的行为叫做赋值,因此改成直到构造函数执行完才真正获得const属性可能更好。 (欢迎批判)
三.P245 可变数据成员
如果成员函数是const修饰,那么其成员变量将不能修改,但是用mutable关键字修饰的成员变量依旧可以修改。
mutable不受const修饰的成语函数限制。
class A {
mutable int i;
int j;
public:
void func(int a)const {
i = a;//正确
j = a;//错误
}
};
四.P250 类的声明
类的成员中不能有同类对象。
class A {
A a;//错误
};
这是因为同类成员需要初始化,但成员处在自己类的内部,类对象本身都还未完成初始化,内部同类成员又怎么可能完成初始化呢。
但是成员可以是指向自己的指针或引用,因为使用指针或引用时,一定是一个已经初始化的对象。
class A {
A* a;//正确
};
构造函数体中也可以定义同类对象,因为此时已经走完初始化列表完成初始化。
class A {
public:
A(){
A a;//正确
}
};
成员也可以是静态同类成员。 因为静态成员需要在类外进行,定义类内只是声明,且只属于类本身,不属于任何类对象。
class A {
public:
static A a;//声明
};
A a;//定义
五.P261 委托构造函数
委托构造函数可以“委托”其他同类构造函数执行初始化过程,且委托构造只能在初始化列表中调用
class A {
int i;
int j;
public:
A(int a, int b)
{
i = a;
j = b;
}
A()
:A(1, 2)//委托构造
{};
};
如果我们调用默认构造创建A类对象,那么调用默认构造时会先调用带参数的构造函数,执行完毕后再将“控制权”还给默认构造。