C++ 如何返回一个类成员变量的引用

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 类型就没问题

阅读 9.7k
2 个回答
P& Foo::getp() const 
{
    return const_cast<P&>(this->m_bar);
}

这里只是举个可行的方法 虽然const_cast不应该这样用.

至于你的写法为什么不能通过呢? 你必须知道P& Foo::getp() const 中的const有无分别代表着什么:

没有const时:


this指针在这里的类型是Foo*. 为什么不是Foo* const呢? 因为this不是lvalue(左值), 而是一个prvalue.

N4713

8.2.1

Unless otherwise indicated (8.5.1.2), a prvalue shall always have complete type or the void type......Class and array prvalues can have cv-qualified types; other prvalues always have cv-unqualified types. See 8.2.

cppreference

A non-class non-array prvalue cannot be cv-qualified. (Note: a function call or cast expression may result in a prvalue of non-class cv-qualified type, but the cv-qualifier is immediately stripped out.).

所以this在没有const修饰时只能是T*, 不能是T* const.


有const时:

this指针的类型就是Foo const*(或者是const Foo*, 这两者是等价的). 从右往左读: pointer to const Foo. 意思就是:

  • this只向的Foo对象是const的, 所以this->data_member = ...是非法的.

接下来的你的问题就很明显了. 因为你在函数后面用const修饰了, 所以this是const Foo*类型. 也就是说m_bar是不可修改的, 如何保证这一点呢? 自然是返回值也是const啦. 这就是@araraloren 说的做法. 至于开头我说的那种做法, 就是去掉了const, 虽然在这里能解决, 不过可以说是bad practice.

class P {};
class Foo {
    protected: // ! 此处应该是 public
    const P& getp() const; // 返回值 必须是 const &
        
    private:
    P m_bar;
};

const P& Foo::getp() const {
    return m_bar;
}

int main()
{
    Foo f;
    P p1 = f.getp(); // ! 此处语法错误 
}

结论L:基础太薄弱,须加强练习。。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏