1、const可以实现常函数
(1)常函数,就是class的成员函数承诺在函数内部不会修改class的任何成员变量,注意是任何一个
(2)常函数演示案例
#include <string>
#include <iostream>
using namespace std;
/*****************定义一个类***********************/
class person
{
public:
string name; // 名字
bool male; // 性别,男为true,女为false
person(){};
person(int myage);
void AgeAdd1(void);
int AgeGet(void) const; //定义为常函数,编写类的人承诺在这个函数里面不会修改任意一个成员变量
private:
int age; // 年龄
};
/****************实现类方法*************************/
person::person(int myage) //自定义构造函数
{
this->age = myage;
}
// 人长大了一岁,所以age++,所以这个方法不是一个常函数,因为内部改变了成员变量的值
void person::AgeAdd1(void)
{
this->age++;
}
// 本函数只是读取class的成员变量,并不修改,所以可以是常函数
int person::AgeGet(void) const
{
//age++;
return this->age;
}
/*****************类的使用者******************/
// 对于person类的使用者,使用类的时候会封装一些函数来完成功能,函数传参的时候会用引用
void PrintAge(const person& pn)
{
// 写PrintAge函数的人,心里很清楚,AgeGet的调用绝对不会修改pn对象的任何一个成员变量
cout <<"person.age = " << pn.AgeGet() << endl;
}
int main(void)
{
person p1(23);
//p1.AgeAdd1(); // 写main函数的人,调用这个方法时,心里很清楚有可能会修改p1对象的成员变量
PrintAge(p1);
return 0;
}
在上面的例子中int AgeGet(void) const;
定义为常函数,编写类的人承诺在这个函数里面不会修改任意一个成员变量;所以在调用这个方法的时候写PrintAge函数的人,心里很清楚,AgeGet的调用绝对不会修改pn对象的任何一个成员变量。
现在我们尝试在声明为const常函数里面修改成员变量:
// 本函数只是读取class的成员变量,并不修改,所以可以是常函数
int person::AgeGet(void) const
{
age++; //改变成员变量的值
return this->age;
}
总结:上例中const函数调用存在一个承诺链条:在使用类库的人中,它实现了一个方法void PrintAge(const person& pn)
,它向main()函数承诺,我不会修改你给我传的参数即引用,所以main()函数中,person p1(23); PrintAge(p1);
而在PrintAge(const person& pn)
里面的pn.AgeGet() ;
函数就向PrintAge承诺我不会在AgeGet()函数里面修改成员变量的值,所以你调用我的时候也要传const的参数。
(3)思考:C++为什么设计常函数?是为了class的设计者和使用者更好的协作,避免错误的使用类库
2、mutable可以局部打破const常函数
(1)const常函数承诺在函数内不会修改class的任何一个成员变量
(2)但是有时候个别成员变量,就是需要在const的常函数中也能修改(注意只是个别,其他大部分是不需要修改的)
(3)怎么办?2个解法:要么去掉const,要么使用mutable局部打洞
(4)mutable使用演示
定义类的时候用mutable修饰想要在const函数中访问的成员变量。
class person
{
public:
mutable string name; // 给name 成员变量打洞
bool male; // 性别,男为true,女为false
person(){};
person(int myage);
void AgeAdd1(void);
int AgeGet(void) const; //定义为常函数,编写类的人承诺在这个函数里面不会修改任意一个成员变量
private:
mutable int age; // 给age成员打洞
};
在const函数中可以改变mutable修饰的成员变量。
int person::AgeGet(void) const
{
age++;
name = "ddd";
return this->age;
}
(5)思考:C++为什么设计mutable?和private那里一样,还是先全部禁了再按需打开的思路。