常对象指的是使用 const 关键字修饰的类对象,常函数指的是由 const 关键字修饰的函数。这里需要注意:只有成员函数才可以被 const 关键字修饰,而全局函数无法被 const 关键字修饰。
- 常函数 {#title-0} =================
在成员函数的后面加上 const, 该函数就变成了常函数,常函数会保证不修改成员变量的值,如果修改则编译报错,非常函数仍然可以修改成员变量的值。其本质是在修饰成员函数的 this 指针。原本的 this 指针指向的内存空间是可以修改的,当被 const 修饰之后,其指向的内存空间也不能修改,即: 对象的成员变量无法修改。
但是,当成员变量使用 mutable 修饰时,不收到 const 成员函数的限制。
class Demo
{
public:
Demo(int a,int b)
{
m_a = a;
m_b = b;
}
void func()
{
m_a = 200;
}
// const 到底修饰的是什么东西?
// const 修饰的是成员函数的第一个参数 this 指针
// this 指针原来是指针常量: const Demo * const this
void show() const
{
// this->m_a = 100;
m_b = 200;
cout << m_a << " " << m_b << endl;
}
public:
int m_a;
// 希望某些成员变量能够在常函数中修改,那么需要对成员变量使用 mutable 关键字修饰
mutable int m_b;
};
// 常对象 : 使用 const 限定的对象
void test01()
{
// demo 就是一个常量对象,就是不能修改的对象
// 所谓的修改指的是:成员变量
const Demo demo(10, 20);
cout << demo.m_a << " " << demo.m_b << endl;
// 以下代码试图修改对象,编译错误
// demo.m_a = 100;
// demo.m_b = 200;
// 为什么常对象不能调用成员函数呢?
// 编译期不确定,show 函数会不会修改对象的成员变量 m_a 和 m_b
demo.show();
}
- 常对象 {#title-1} =================
常对象指的是使用 const 关键字修饰的类对象,表示该对象除了 mutable 修饰的成员变量之外,都不可以修改。所以,对于常对象而言只能调用常函数。
class Person
{
public:
Person(string name, int age)
{
m_name = name;
m_age = age;
}
void print() const
{
cout << m_name << " " << m_age << endl;
}
public:
string m_name;
int m_age;
};
void print_person(const Person& person)
{
person.print();
}
void test02()
{
Person person("smith", 20);
print_person(person);
}