类的相关知识(二)const
const修饰对象
class Role
{
public:
int hp;
void addhp(Role& r)
{
hp+=100;
}
int& gethp() const
{
return hp;
}
}
int main()
{
const Role hero;
hero.hp=199;
Role NPC;
NPC.gethp()=200;
const Role* ptr=&NPC;
ptr->hp=100;
sethp(Role& r)
}
const修饰的对象不能更改它成员变量的值,这里hero的hp不能被修改,const修饰的指针指向的内存也不能修改,即ptr指向的hp也不能修改,因为ptr的类型是常量,编译器会把它看作是指向常量的指针,所以不会让它指向的值修改,同样因为这个原因,ptr不能访问addhp,为什么这里没写完呢?因为ptr根本就不能访问,更别提修改它的值了,那怎么修改呢?要给addhp函数添加const修饰即可
void addhp(Role& r) const
{
hp+=100;
}
为什么不能放到前面呢?因为放在前面,就相当于声明了返回值类型为const,const修饰的成员函数,函数内部不能修改成员属性的值
因为const的原则,即const对象不能以任何方式改变,就产生了一系列效应,比如const对象只能调用const成员函数,另一个变化是在const成员函数内,this指针也变成了const指针
const修饰返回值
像上面,当NPC调用sethp时,也不能通过编译,因为返回的是一个引用,引用意味着有修改hp的可能性,所以不能这样调用,除非在函数头前面加上const,或者去掉引用,加const就告诉了编译器返回值虽然是个引用,但是也不能修改
const int& gethp() const
{
return hp;
}
因为const对象只能调用const成员函数,有时候const对象如果想要调用其他成员函数,怎么办呢?有两个办法,1是利用函数重载,重新声明一个函数相同,参数名不同的函数,一个加const,一个不加const,2是在每个不修改成员函数的函数后面都加上const。
const类型转换、
void func(Role* r)
{
}
const Role r;
func( &r );
func( (Role *) &r);
func(const_cast<Role*> &r)
这里,实参和形参类型不符合,就要用到类型转换
mutable
上面我们说过,const修饰的成员函数,函数内部不能修改成员属性的值,但是,当属性被mutable关键字修饰的时候,属性就能够在函数内被修改。
语法 mutable int hp;