C++ const常量、常函数和常量对象
目录
常量
特性
初始化顺序
常函数
定义
回顾常量指针与指针常量
指针安全级别升级、降级问题
常函数特性
常函数与其他函数之间的调用
在常函数中修改变量
常量对象
定义
测试mutable关键字
总结
常量
常函数
常量对象
常量
特性
定义就必须初始化,一旦初始化后就不能再取修改其值(不能通过正常手段修改)。
初始化
当类中有const类型的变量时,在定义的时候必须要初始化,而这个初始化操作是在初始化参数列表中完成的,而构造函数的函数体代码中进行的操作严格来说是赋值,而并非初始化。先执行初始化参数列表,再执行构造函数体中的代码。对于普通的变量也可在初始化参数列表中初始化。
写法:在构造函数的参数列表后加上一个冒号:后面是初始化的成员,用圆括号()的形式指定初始化值(而不是用=等号),多个成员用逗号,分割。
注意:一般的函数无初始化参数列表
class CTest {
public:const int m_a;int m_b; //mutable 修饰类成员变量,在常函数或常量对象中是可变的CTest() :m_a(10),m_b(20){//m_a = 10; //严格来说,这里是赋值操作,而不是真正的初始化操作, error: 必须初始化常量限定类型的对象m_b = 30; //赋值}//void fun():m_a(20){} //一般的函数无初始化参数列表};
初始化顺序
初始化成员顺序为成员在类中定义的顺序,而不是写在初始化参数列表中的顺序。
CTest(int a) :m_a(a),m_b(m_a) {}
常函数
定义
类中的成员函数参数列表后面有const修饰时,称之为常函数,其主要作用就是为了能够保护类中的成员变量、限制修改。
void fun()const {}
回顾常量指针与指针常量
int a = 0;const int b = 1;
常量指针:const 修饰的是【*p1】,指针指向的空间(int)里面的值不能改,但是指针的指向(int*)可以改。
//常量指针const int* p1 = &a; //*p1 = 3; //非法p1 = &b; //合法
指针常量: const:修饰的是【p2】,指针指向的空间(int)里面的值 可以改,但是指针的指向(int*)不能改。
注意:1.必须要初始化,此时不初始化,后期也不能赋值或者改变空间
2.不可以指向常量,会语法矛盾
//指针常量int* const p2 = &a; *p2 = 4;//合法//p2=&a; //非法
指针安全级别升级、降级问题
指针安全级别升级,合法;
指针安全级别降级,非法;
int* p3 = &a;const int* p4 = p3; //指针安全级别升级,合法//p3 = p4; //指针安全级别降级,非法
常函数特性
不能修改类中的非静态成员,因为const修饰的this指针变为了const 类* const this(CTest* const this -> const CTest* const this),也就是执行this->变量=val是非法操作了,但是可以查看成员变量。对于静态成员属性不但能查看,也能对其修改,因为静态成员不是属于对象的,不在const约束范围内。
在常函数中,即使是一个变量,但是通过this指针调用的,this指针类型有双重const修饰,意味着对象中任何成员不能通过this指针修改。
常函数与其他函数之间的调用
在常函数中可以查看普通的变量、常量、静态变量等,也可以调用其他常函数,但是却不能调用普通的成员函数,因为其this指针的类型不相同。
常函数调用普通的类成员函数:
void fun2(/* CTest* const this */) {}
void fun(/* const CTest* const this */)const {//fun2(); }
这其中this指针的变化:const CTest* const this -> CTest* const this,由此可以看出this指针降级的一个操作,所以在常函数中不能调用普通的类成员函数。
普通的类成员函数调用常函数:
void fun2(/* CTest* const this */) {fun();//升级操作,可以的}
这里是升级操作,所以是可以的。
在常函数中的静态成员:
static int m_c;static void fun3(/* 无this指针 */) {}
int CTest::m_c = 0;
注意别忘了静态成员要在类外定义
静态成员属性,不受this指针约束,能用能改,静态成员函数当然也可以调用。
cout << m_c << endl;m_c = 1; //静态的成员属性,不受this指针约束,能用能改fun3(); //可以调用
但是反过来,静态成员函数调用不了普通的成员函数,因为静态成员函数中没有this指针,所以更是调用不了常函数。
static void fun3(/* 无this指针 */) {//fun(); //调用不了普通的成员//fun2();}
在常函数中修改变量
在常函数中要修改变量有两种方法,一种是通过指针间接修改,还有一种就是在定义时用mutable关键字修饰要修改的成员变量。
方法一:
cout << "this->m_b = " << this->m_b << endl;int* p = (int*)&this->m_b;*p = 10;cout << m_b << endl;
方法二:
mutable int m_b;
m_b = 20;cout << m_b << endl;
常量对象
定义
常量对象:使用const修饰的对象(如const CTest tst;)不能调用普通的成员函数,只能调用常函数。这里面涉及到了this指针的安全级别升级还是降级的操作。
测试mutable关键字
const CTest tst2;tst2.m_b = 50;cout << tst.m_b << endl;
总结
常量
定义就必须初始化,初始化后不能通过正常手段修改;
类中const类型的变量的初始化是在初始化参数列表中完成的;
注意初始化顺序。
常函数
注意this指针升级降级问题,升级合法,降级不合法;
常函数不能调用普通成员函数,但普通成员函数能调用常函数;
常函数能调用静态成员函数,但静态成员函数不能调用普通成员函数以及常函数。
常量对象
mutable 修饰类成员变量,在常函数或常量对象中是可变的。