-
const- 就是将对象修饰为
常量类型,就是不可修改类型,比如const int* p;:const修饰的是p指向的那块内存,p可以重新赋值,但是*p不能int const* p;:const修饰的是p指向的那块内存,p可以重新赋值,但是*p不能,跟上面一样int* const p;:const修饰的是p的地址,p不可以重新赋值,但是*p可以
- 如果函数的形参是
const类型,则这个参数不能被修改,一般用来保护传进来的对象不被本函数篡改 const类型的变量在离开作用于后会被释放- 如果类成员变量是
const类型,则需要在构造函数的初始化列表定义,要求一定要有构造函数,比如
class Test { public: Test() : m_nId(0) {} private: const int m_nId; };- 之所以需要在构造函数的初始化列表定义,是因为
const成员变量对于类来说是不存在的,其只存在于对象的生存期,也就是说类只有实例化成对象了,这个const类成员对象才是一个常量,所以不能在类声明的地方定义,因为此时类还没实例化 - 如果类成员函数是
const类型,那么在这个函数内,不能修改类成员变量,其实就是将this指针修饰为const const成员函数不能调用非const成员函数,因为在类成员函数的形参列表里,其实隐式塞入了一个this指针,如果是const的成员函数,那么这个指针的类型就是const T* this,但是非const成员函数的指针类型是T* this,两者不匹配,所以无法调用。燃鹅,非const成员函数可以调用const成员函数,因为C++里有个最小权限原则,我的理解是,非const权限大,const权限小,小的不能调用大的,大的能调用小的const对象不能调用非const成员函数,非const对象可以调用const成员函数,原理同上- 类成员函数中有两个地方可以填上
const- 函数名前,表示返回的值是
const - 函数名后,表示这个函数是
const,也就是上面说的const成员函数
- 函数名前,表示返回的值是
- 用
const来修饰对象有两种情况- 对象为基本类型,在编译时,直接用常量来替换,比如下面代码,在编译
cout << a << endl;时,编译器已经将a优化为1,也就是cout << 1 << endl;,虽然此时a所在的内存的值为2
const int a = 1; int* p = const_cast<int*>(&a); *p = 2; cout << a << endl; // 1 cout << *p << endl; // 2- 对象为结构体或类,编译时,先用一个内存地址替换,比如下面代码
struct Test { int a; Test() : a(1) {} }; const Test t; const int b = 2; int* p1 = const_cast<int*>(&t.a); int* p2 = const_cast<int*>(&b); *p1 = 100; *p2 = 200; cout << t.a << endl; // 100,因为是结构体,通过地址取的,所以值变了 cout << b << endl; // 2,基本类型,被优化成常量了 - 对象为基本类型,在编译时,直接用常量来替换,比如下面代码,在编译
- 就是将对象修饰为
-
staticstatic变量默认初始化为0,存在.data段- 全局静态变量,只能本文件访问,其他文件无法访问,但可以命名一个跟他一模一样的全局静态变量
- 局部静态变量,在函数结束后不会被释放,下次再进入这个函数时,维持上一次的值
- 静态函数,跟静态全局变量一样,只能本文件访问,其他文件无法访问
- 对于类而言
- 静态成员变量
- 属于类,不属于对象,对于该类所实例化出来的对象而言,静态成员是被所有对象共享的,内存里只有一份,因为这些静态成员变量是存在
.data段,而不是对象所在的堆或栈 - 类里有静态成员变量,需要在类外进行定义,比如
class Test { private: int m_nStatic; public: static void DoTest(){} }; int Test::m_nStatic = 1; - 属于类,不属于对象,对于该类所实例化出来的对象而言,静态成员是被所有对象共享的,内存里只有一份,因为这些静态成员变量是存在
- 静态成员函数
- 没有
this指针,所以类里不能出现const static的成员函数,同时也不能为虚函数 - 没有
this指针,不能直接访问,需要Test::DoTest();这样来访问 - 这类的函数不能访问非静态的成员函数,如果真要访问,只能在形参里手动添加对象指针或引用,访问非静态成员变量也是如此
- 没有
- 静态成员变量