C++学习笔记:const和mutable

1.const可以实现常函数

所谓的常函数,就是class的成员函数承诺在函数内部不会修改class的任何成员变量(注意是任何一个)。

实现语法是在函数名后面加上const,举个栗子:

#include<iostream>

using namespace;

class person
{
    
    
public:
	person(int 	Age):age(Age){
    
    };
	//get_age()函数只读取age的值,没有修改任何成员,因此可以是常函数
	int get_age(void) const	
	{
    
    
		return this->age;
	}
private:
	int age;
};

int main(int argc,char**argv)
{
    
    
	person tom(15);
	int age=tom.get_age();
	cout<<age<<endl;
	return 0;
}

输出:

15

2.C++为什么设计常函数

对于person类的使用者来说,上面的get_age()函数典型的用法并不是tom.get_age(),而是通过一层封装得到新的函数来完成功能,函数通过引用来传参。例如通过获取年龄函数封装出一个打印年龄的函数:

void show_age(const person&pn)
{
    
    
	cout<<"age = "<<pn.get_age()<<endl;
}

在上面的函数中,作为类的设计者,因为提前知道获取年龄并不会修改年龄这个成员,所以在get_age()函数后加上const表面这是一个常函数。而在后面类的使用者封装show_age()函数时,同样该函数不需要修改年龄,所以在引用前加上const

C++要求一个函数传参为引用对象的时候,函数内部调用的所有类的成员函数必须是常函数。也就是说show_age()参数为const person&pn时,get_age()必须实现成常函数,否则编译会报错。

思考:C++为什么设计const常函数?还是为了class的设计者和使用者更好的协作,避免错误的使用类库。

3.mutable可以局部打破const常函数

void show_age(const person&pn)
{
    
    
	cout<<"age = "<<pn.get_age()<<endl;
}

对于上面的show_age()函数,参数为const person&pn,则函数内部对pn调用的方法必须都是常函数方法。但是有时候个别成员变量,就是需要在const的常函数中也能修改(注意只是个别,其他大部分是不需要修改的),
怎么办?

有2个解决方法:

  • 1.去掉const,让它不再是常函数。
  • 2.使用mutable局部打洞。

mutable使用方法就是在需要局部打洞的变量前加上mutable,举个栗子:

#include<iostream>
#include<string>

using namespace;

class person
{
    
    
private:
	//在需要局部打洞的变量前加上mutable
	mutable int age;
	string name;
public:
	person(int 	Age):age(Age){
    
    };
	//get_age()函数只读取age的值,没有修改任何成员,因此可以是常函数
	int get_age(void) const	
	{
    
    
		//name="zhangsan"; name不可以修改,但是也可以加mutable使其可以修改
		age++;//这里age就可以修改了
		return this->age;
	}
};

int main(int argc,char**argv)
{
    
    
	person tom(15);
	int age=tom.get_age();
	cout<<age<<endl;
	return 0;
}

输出:

16

思考:C++为什么设计mutable?本质是“先全部禁了再按需打开”的思路。先用const把函数变为常函数,封上它修改所有成员的道路,然后用mutable去打洞,需要修改哪个就打哪个的洞。

猜你喜欢

转载自blog.csdn.net/PecoHe/article/details/113172750