为何在const成员函数中,通过指针调用非const成员函数无编译错误?
为什么const成员函数中通过指针调用非const成员函数不报错,直接调用对象却触发C2662?
核心原因:const成员函数对不同类型成员变量的约束不同
在类的const成员函数中,编译器会对成员变量施加差异化的const属性约束:
- 非指针成员变量(比如示例中的
_object):整个对象会被视为const类型(即const Member),调用它的非const成员函数会因this指针类型不匹配报错。 - 指针成员变量(比如示例中的
_pointer):约束仅作用于指针本身(指针变为Member* const,即不能修改指针指向的内存地址),但指针指向的对象仍然是非const的Member,因此可以正常调用非const成员函数。
结合代码细节拆解
先看Member::GetValue()的定义:它是一个非const成员函数,其隐含的this指针类型为Member&(非const引用)。C++规定,非const成员函数只能被非const对象调用,因为这类函数可能修改对象内部状态。
GetValueUsingPointer()正常编译的原因
在const成员函数中,_pointer是Member* const类型,但*_pointer获取到的是指针指向的非constMember对象。调用(*_pointer).GetValue()时,this指针可以正常匹配Member&类型,因此编译通过。GetValueUsingObject()触发C2662的原因
在const成员函数中,_object被视为const Member类型。调用它的非const成员函数GetValue()时,需要将const Member*类型的this指针转换为Member&,而C++不允许将const对象隐式转换为非const引用(这会破坏const的只读承诺),因此触发编译错误:
C2662 'int Member::GetValue(void)' : cannot convert 'this' pointer from 'const Member' to 'Member &'
修复方案参考
如果希望GetValueUsingObject()能正常编译,有两种常见思路:
- 若
GetValue()不需要修改成员变量:将其声明为const成员函数,修改为int GetValue() const { return _value; }(需移除对_value的赋值,因为const成员函数不能修改非mutable成员变量)。 - 若
GetValue()必须修改成员变量:则Test的GetValueUsingObject()不能声明为const成员函数,因为它会修改_object的内部状态,违反const成员函数的只读约定。
内容的提问来源于stack exchange,提问作者이종명
相关产品推荐
相关产品推荐

