C++ 中 const 成员函数的本质

const 成员函数形如:

class Test {
public:
  void fun() const;
};

先看一段非常好的英文解释:

A “const function”, denoted with the keyword const after a function declaration, makes it a compiler error for this class function to change a member variable of the class. However, reading of a class variables is okay inside of the function, but writing inside of this function will generate a compiler error.

重点是下面一段,抽空翻译:
Another way of thinking about such “const function” is by viewing a class function as a normal function taking an implicit this pointer. So a method int Foo::Bar(int random_arg) (without the const at the end) results in a function like int Foo_Bar(Foo* this, int random_arg), and a call such as Foo f; f.Bar(4) will internally correspond to something like Foo f; Foo_Bar(&f, 4). Now adding the const at the end (int Foo::Bar(int random_arg) const) can then be understood as a declaration with a const this pointer: int Foo_Bar(const Foo* this, int random_arg). Since the type of this in such case is const, no modifications of member variables are possible.

It is possible to loosen the “const function” restriction of not allowing the function to write to any variable of a class. To allow some of the variables to be writable even when the function is marked as a “const function”, these class variables are marked with the keyword mutable. Thus, if a class variable is marked as mutable, and a “const function” writes to this variable then the code will compile cleanly and the variable is possible to change. (C++11)

As usual when dealing with the const keyword, changing the location of the const key word in a C++ statement has entirely different meanings. The above usage of const only applies when adding const to the end of the function declaration after the parenthesis.

const is a highly overused qualifier in C++: the syntax and ordering is often not straightforward in combination with pointers. Some readings about const correctness and the const keyword:

Const correctness

The C++ ‘const’ Declaration: Why & How

https://stackoverflow.com/questions/3141087/what-is-meant-with-const-at-end-of-function-declaration

提炼重点:

const 成员函数 void fun() const 被编译为 void Test_fun(const Test* this)

const 成员函数 void fun() 被编译为 void Test_fun(Test* this)

区别在于传入的 this 指针类型不同

由此引发出了一种有意思的重载,即 const 成员函数重载,如下

#include<iostream>
using namespace std;
 
class Test
{
protected:
    int x;
public:
    Test (int i):x(i) { }
    void fun() const
    {
        cout << "fun() const called " << endl;
    }
    void fun()
    {
        cout << "fun() called " << endl;
    }
};
 
int main()
{
    Test t1 (10);
    const Test t2 (20);
    t1.fun();
    t2.fun();
    return 0;
}

代码输出为:

fun() called 
fun() const called 

可以这么理解,

编译后两个 fun 函数分别为 void Test_fun(Test* this)void Test_fun(const Test* this)

调用 t.fun() 时,实质上是 t.fun(&t)

t1 类型为 Test&t1 对应 void Test_fun(Test* this)

t2 类型为 const Test&t2 对应 void Test_fun(const Test* this)

这就是发生的重载

由此再引申一点:

如果注释掉类里面的 const 函数,则报错,无法运行

如果注释掉 非const 函数,不报错,两次都调用 const 函数

也就是说,void Test_fun(const Test* this) 可以接收 const非const 类型

但是 void Test_fun(Test* this) 却只能接收 非const 类型,不能接收 const 类型

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值