1.constexpr 一方面是为了引入更多的编译时计算能力,修饰函数可以在编译时期就计算出函数的值,前期是函数的输入参数也是明确的。
2. 初始化列表
C++11 提供了统一的语法来初始化任意的对象。类的成员初始化可以统一使用初始化列表,如果类的成员是引用成员(&修饰)或者 const变量只能使用初始化列表。
class B { B(int _a, float _b): a(_a), b(_b) {} private: int a; float b; }; B b{2, 2.2};// 统一的初始化语法 //没有使用初始化列表将会出错
class people{ public: people(int i){ age=i; std::cout<<"age:"<<age<<std::endl; } private: int& age; }; int main(){ people p(10); return 0; } 编译报错:error: uninitialized reference member ‘people::age’ [-fpermissive] 原因:age使用&修饰后,没有在初始化列表中对引用成员进行初
3.
int* const p=&a;表示指针不可变
const int *p=&a;表示指向的内容不可变。
7.用const 修饰函数的返回值
如果给以“指针传递”方式的函数返回值加const 修饰,那么函数返回值(即指针)的内容不能被修改,该返回值只能被赋给加const 修饰的同类型指针。 const与define功能相似,具有定义常量功能。const 定义的常量,在内存中只由一个,没有多个拷贝。
1.修饰入参,不能修饰出参,表示该参数在函数内部不能被修改,这个只有在引用传递或者指针传递时起作用,值传递时会产生临时对象,不会对原对象产生影响。
2.修饰类成员函数,表示该成员函数不能修改类的其他成员,而且不能调用非const函数。
3.const修饰成员变量,该变量只能在初始化列表中进行初始化。包括成员变量是引用类型。
4.修饰变量,表示该变量不能被修改,必须在定义时初始化。
5.const关键字不能与static关键字同时修饰成员函数,因为static关键字修饰静态成员函数,静态成员函数不含有this指针,即不能实例化,const成员函数必须具体到某一实例。
void change(const student * ss){ //指针指向的内容不被修改 ss->a = 22; //报错:‘student::a’ in read-only object ss->say(); }
void change( student * const ss){ //指针不被修改 ss->a = 22; ss->say(); }
6. 用const来修饰返回的指针或引用,保护指针指向的内容或引用的内容不被修改,也常用于运算符重载。归根究底就是 使得函数调用表达式不能作为左值。
constexpr可以用来修饰变量、函数、构造函数。任何元素被constexpr修饰,在编译阶段就计算出函数返回值,并用常量去替代这个函数。
constexpr int func() { return 10; } main(){ int arr[func()]; } //error : 函数调用在常量表达式中必须具有常量值 编译期大胆地将func()做了优化,在编译期就确定了func计算出的值10而无需等到运行时再去计算。 如果用const或者去掉constexpr,编译阶段会报错。
const 告诉编译器这个变量只能被初始化,且不能被直接修改。
在类内初始化静态成员,那么就必须满足如下条件才行:
1) 静态成员必须为字面值常量类型:constexpr。
2)给静态成员提供的初始值,必须为常量表达式,c++11后建议统一使用constexpr来修饰。
class A{ public: static int a; static int a=1; //报错 ISO C++ forbids in-class initialization of non-const static member static const int b = 1; //正确 static const double pi1 = 3.14;//报错 static constexpr double pi3 = 3.14;//正确 } int A:: a=10; //类外初始化,不带static
总之总结两句就是:
1.禁止在在类内初始化非const静态变量。 ISO C++ forbids in-class initialization of non-const static member
2.静态成员只有一个副本,所有的类对象共用。而非静态成员每个对象有一个副本。