> 文章列表 > C++ const常量、常函数和常量对象

C++ const常量、常函数和常量对象

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 修饰类成员变量,在常函数或常量对象中是可变的。