class P {};class Foo { protected: P& getp() const; private: P m_bar;};P& Foo::getp() const { return m_bar;}int main(){ Foo f; P p1 = f.getp()}
上述代码在调用getp时编译出问题,但是把 P 换成 string 类型就没问题
解决方案
P& Foo::getp() const { return const_cast<P&>(this->m_bar);}
这里只是举个可行的方法 虽然const_cast不应该这样用.
至于你的写法为什么不能通过呢? 你必须知道P& Foo::getp() const
中的const有无分别代表着什么:
- 没有const时: this指针在这里的类型是
Foo* const
. 这是什么意思呢? 我们需要反着读: const point to Foo也就是说this指针本身是const, 不能只想其他对象了, 但是它指向的对象不是const, 所以能修改. 有const时: this指针的类型就是
Foo const* const
(或者是const Foo* const
, 这两者是等价的). 好, 我们继续从右往左读: const pointer to const Foo. 意思就是:- this本身是一个const指针, 它不能只想其他对象, 比如
this = another_pointer
是非法的. - this只想的Foo对象也是const的, 所以
this->data_member = ...
也是非法的.
- this本身是一个const指针, 它不能只想其他对象, 比如
接下来的你的问题就很明显了. 因为你在函数后面用const修饰了, 所以this是const Foo* const
类型. 也就是说m_bar
是不可修改的, 如何保证这一点呢? 自然是返回值也是const啦. 这就是@araraloren 说的做法. 至于开头我说的那种做法, 就是去掉了const, 虽然在这里能解决, 不过可以说是bad practice.