常对象指的是使用 const 关键字修饰的类对象,常函数指的是由 const 关键字修饰的函数。这里需要注意:只有成员函数才可以被 const 关键字修饰,而全局函数无法被 const 关键字修饰。
1. 常函数
在成员函数的后面加上 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(); }
2. 常对象
常对象指的是使用 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); }