7. 常成员函数

常成员函数 是使用常声明(const)方法声明一个普通的成员函数只能读取其对象的成员变量,但不能修改其成员变量。一旦在函数内修改成员变量,则编译器报错。

常成员函数内的 this 指针被设定为只读(添加了 const 属性),因此无法修改其成员变量。

常成员函数的使用场景:

  1. 没有常属性的对象可以调用普通成员函数,也可以调用常成员函数。
  2. 具有常属性(const)的常对象只能调用常成员函数。

与普通成员函数一样,常成员函数也有类内声明类内实现类内声明类外实现两种语法形式。

常成员函数类内声明类内实现的语法

class 类名{
   public:
      // 类内声明,类内实现。
      返回类型 成员函数名(形式参数列表) const { ... };
}

常成员函数类内声明,类外实现的语法

class 类名{
   public:
      // 类内声明。
      返回类型 函数名2(形式参数列表) const;
}

类外实现的语法

返回类型 类名::函数名2(形式参数列表) const { ... }

示例

// filename: const_member_func
#include <iostream>
#include <string>

using namespace std;

class Person {
    public:
        Person(const string & n, int a): name(n), age(a)  {
            cout << "创建:Person(" << n << ", " << a << ");\n";
        }
        ~Person(void) {
            cout << "析构:~Person(" << name << ", " << age << ");\n";
        }
        int getAge(void) const; // 类内声明
    private:
        string name; // 姓名
        int age; // 年龄
};

// 常成员函数的类外实现
int Person::getAge(void) const {
    return this->age;
}

int main(int argc, char * argv[]) {
    Person p1("老魏", 35); 
    const Person p2("魏明择", 25); 

    cout << "p1的年龄:" << p1.getAge() << endl;
    cout << "p2的年龄:" << p2.getAge() << endl;

    return 0;
}

编译和运行结果如下:

weimz@mzstudio:~$ g++ -o const_member_func const_member_func.cpp
.weimz@mzstudio:~$ ./const_member_func 
创建:Person(老魏, 35);
创建:Person(魏明择, 25);
p1的年龄:35
p2的年龄:25
析构:~Person(魏明择, 25);
析构:~Person(老魏, 35);

实验

尝试将自己编写的类的只读成员函数都改成常成员函数。