C++中const修饰成员函数

 更新时间:2026年02月03日 08:34:48   作者:挖矿大亨  
本文主要介绍了C++中const修饰成员函数,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

一、const 成员函数的核心定义

const修饰成员函数时,要写在函数参数列表后、函数体前(有virtual则在virtual后),其核心作用是:保证该成员函数不会修改当前对象的任何非静态成员变量,且只能调用其他 const 成员函数。
语法格式:

// 声明(类内)
返回值类型 函数名(参数列表) const;

// 定义(类外)
返回值类型 类名::函数名(参数列表) const {
    // 函数体
}

二、为什么需要 const 成员函数?

核心目的是保证 “常量对象” 的只读性—— 当一个对象被声明为const(常量对象)时,编译器要求它只能调用const成员函数,防止对象被意外修改。
先看一个没有 const 成员函数的反例:

#include <iostream>
using namespace std;

class Person {
public:
    int age = 20;

    // 普通成员函数:可修改成员变量
    void showAge() {
        cout << "Age: " << age << endl;
        // 即使没修改,编译器也认为这个函数“可能修改”对象
    }
};

int main() {
    // 常量对象:不允许被修改
    const Person p;
    p.showAge(); // 编译报错!常量对象不能调用普通成员函数

    return 0;
}

报错原因:编译器无法确定showAge()是否会修改p,因此禁止常量对象调用普通成员函数 —— 而const成员函数就是用来告诉编译器:“这个函数绝对不会修改对象,放心让常量对象调用”。

三、const 成员函数的使用规则(核心)

1.基础规则:const 成员函数不能修改非静态成员变量

#include <iostream>
using namespace std;

class Person {
public:
    int age = 20;
    static int total = 0; // 静态成员变量

    // const成员函数:只读,不能修改非静态成员
    void showAge() const {
        cout << "Age: " << age << endl; // 允许:仅读取
        // age = 30; // 编译报错!const函数不能修改非静态成员变量

        total = 100; // 允许:静态成员变量不属于具体对象,不受const限制
    }

    // 普通成员函数:可读写
    void setAge(int a) {
        age = a; // 允许修改
    }
};

int main() {
    // 1. 常量对象:只能调用const成员函数
    const Person p1;
    p1.showAge(); // 正常执行
    // p1.setAge(30); // 编译报错!常量对象不能调用普通成员函数

    // 2. 普通对象:既可以调用const成员函数,也可以调用普通成员函数
    Person p2;
    p2.showAge(); // 正常执行
    p2.setAge(30); // 正常执行

    return 0;
}

2.进阶规则:const 成员函数只能调用其他 const 成员函数

class Person {
public:
    int age = 20;

    void func1() const {
        func2(); // 编译报错!const函数不能调用普通成员函数
        func3(); // 允许:调用其他const成员函数
    }

    void func2() {
        // 普通成员函数
    }

    void func3() const {
        // const成员函数
    }
};

原因:普通成员函数 “可能修改对象”,而 const 成员函数承诺 “不修改对象”,因此不能调用有修改风险的普通成员函数。

3. 例外:mutable 成员变量可被 const 函数修改

mutable(可变的)修饰的成员变量,突破 const 的限制 —— 即使在 const 成员函数中,也能修改mutable成员(用于存储 “逻辑上不影响对象常量性” 的状态,比如缓存、计数):

#include <iostream>
using namespace std;

class Person {
public:
    int age = 20;
    mutable int visitCount = 0; // 可变成员:记录访问次数

    void showAge() const {
        visitCount++; // 允许:mutable成员可被const函数修改
        cout << "Age: " << age << ",访问次数:" << visitCount << endl;
    }
};

int main() {
    const Person p;
    p.showAge(); // 输出:Age: 20,访问次数:1
    p.showAge(); // 输出:Age: 20,访问次数:2
    return 0;
}

四、底层原理:const 修饰的是 this 指针

const 成员函数的本质,是修改了this指针的类型:

  • 普通成员函数中,this的类型是:类类型* const(指针本身不可改,指向的对象可改);
  • const 成员函数中,this的类型是:const 类类型* const(指针本身不可改,指向的对象也不可改)。

编译器视角的伪代码对比:

// 普通成员函数:void showAge(Person* const this)
void Person::showAge() {
    this->age = 30; // 允许:this指向的对象可改
}

// const成员函数:void showAge(const Person* const this)
void Person::showAge() const {
    this->age = 30; // 报错:this指向的对象是const,不可改
}

核心:const成员函数的this指针是 “指向 const 对象的 const 指针”,因此无法通过this修改成员变量 —— 这也是 const 函数不能修改非静态成员的底层原因。

五、const 成员函数的重载

const 成员函数可以和普通成员函数构成重载,编译器会根据调用对象是否为 const,选择对应的版本:

#include <iostream>
using namespace std;

class Person {
public:
    int age = 20;

    // 普通版本:供普通对象调用
    void showAge() {
        cout << "普通版本:Age = " << age << endl;
    }

    // const版本:供常量对象调用
    void showAge() const {
        cout << "const版本:Age = " << age << endl;
    }
};

int main() {
    Person p1; // 普通对象
    p1.showAge(); // 调用普通版本

    const Person p2; // 常量对象
    p2.showAge(); // 调用const版本

    return 0;
}

总结

核心作用:const 成员函数承诺 “不修改对象的非静态成员变量”,让常量对象可以安全调用;

关键规则:

  • 不能修改非静态成员变量(mutable成员除外);
  • 只能调用其他 const 成员函数;
  • 可与普通成员函数构成重载,编译器根据对象是否 const 选择版本;

底层本质:const 修饰的是this指针,使其变为const 类类型* const,限制对对象的修改。
开发建议:只要成员函数不修改对象状态,就声明为 const 成员函数 —— 这是 C++“常量正确性” 的最佳实践,能让代码更健壮、更易维护。

相关文章

  • C++ Virtual关键字的具体使用

    C++ Virtual关键字的具体使用

    这篇文章主要介绍了C++ Virtual关键字的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • c++ 让程序开机自动启动的方法

    c++ 让程序开机自动启动的方法

    这篇文章主要介绍了c++ 让程序开机自动启动的方法,需要的朋友可以参考下
    2017-09-09
  • Qt实现栅格布局效果

    Qt实现栅格布局效果

    这篇文章主要为大家详细介绍了Qt实现栅格布局效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • C++瓦片地图坐标转换的实现详解

    C++瓦片地图坐标转换的实现详解

    常见的瓦片地图有矩形、菱形、正六边形几种。此文章主要讨论菱形瓦片,也就是大家常说的2.5D,斜45度瓦片地图。比如《红警2》、《帝国时代2》都是采用这种技术
    2022-09-09
  • 超详细讲解C++的三种函数传递方式

    超详细讲解C++的三种函数传递方式

    这个文章我将把我学习的有关函数传递形式的知识做个总结,相信很多刚入门的同学看到许多文章五花八门的形参会感到头疼,但本质上无非就是我要说的三种传递形式,快来跟我一起学习吧
    2022-05-05
  • C/C++中指针的深入理解

    C/C++中指针的深入理解

    指针在 C\C++ 语言中是很重要的内容,并且和指针有关的内容一向令初学者头大,这篇文章主要给大家介绍了关于C/C++中指针的相关资料,需要的朋友可以参考下
    2021-07-07
  • C语言浅析函数的用法

    C语言浅析函数的用法

    C语言函数是用来模块化构建程序的。如果你的功能少,你可以全都写在mian函数中,但是当实现功能多的时候,如果全写在main的函数里,不仅代码不美观,而且函数实现的时候结构复杂,代码重复
    2022-07-07
  • 深入理解Qt中各种消息框对话框的使用

    深入理解Qt中各种消息框对话框的使用

    本篇文章主要介绍了Qt中各种消息框的使用,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • 神奇的c/c++小游戏((提高你的编程兴趣)

    神奇的c/c++小游戏((提高你的编程兴趣)

    本文通过c/c++编写小游戏,可以提高新手们的编程兴趣,接下来我们一起来看看吧
    2021-08-08
  • C++计算整数序列的最长递增子序列的长度操作

    C++计算整数序列的最长递增子序列的长度操作

    这篇文章主要介绍了C++计算整数序列的最长递增子序列的长度操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12

最新评论