【问题标题】:Why return string& from a const method won't compile?为什么从 const 方法返回 string& 不会编译?
【发布时间】:2011-08-29 13:24:37
【问题描述】:

给定以下代码:

#include <iostream>
#include <string>
using namespace std;

class A
{
private:
    string m_name;
    string m_first;
public:
    A(): m_first("string") {}
    virtual void print() const {}
    string& getName() const {return m_first;}  // won't compile 
    const string& getLastName() const {return m_name;}  // compile
};


int main()
{
    A a;
    return 0;
}

编译器显示:"invalid initialization of reference of type 'std::string&amp;' from expression of type 'const std::string'" 为什么我不能从 getName() 返回 "m_first" ?我认为函数尾部的 const 表明该函数不会更改 'this'……但我并没有尝试更改 this ,只是返回一个数据成员。

【问题讨论】:

    标签: c++ string reference constants


    【解决方案1】:

    因为在 const 方法内部,所有非mutable 成员都隐含为const。因此,您尝试将对非 const std::string(您的返回值)的引用绑定到 const std::string 类型的对象,这是非法的(因为它允许修改 const 数据),因此会出现错误。

    【讨论】:

    • 如果它允许你这样做,那么调用函数可能会改变你的成员数据。不是将函数标记为 const 的意图。
    • @crashmstr:我不明白 - 我写的东西是否与您的(正确)陈述相矛盾?
    • @Ron_s:如果可以,例如,您可以这样做:a.getName() = "foo";,它会更改 m_first 成员。
    • @Armen:不!你有一个很好的答案。我只是在说明隐含的 const-ness 背后的实际推理。
    【解决方案2】:

    通过返回一个引用,你是说你可以修改引用变量隐式指向的类数据成员,因此修改类......但是你已经将类方法专用于一个常量方法,这意味着不允许更改任何未明确声明为可变的类成员变量。因此,通过返回非常量引用,您打破了类接口已建立的封装“契约”。您的选择是要么返回一个临时对象(即创建对象的副本),要么返回一个常量引用。所以你可以这样做

    const string& getName() const {return m_first;}
    

    string getName() const { return m_first; } //copies m_first and returns the copy
    

    【讨论】:

      【解决方案3】:

      您的代码承诺该引用不会更改 m_name 成员,但您返回一个可以更改它的引用。你想要的是一个字符串 const& 返回类型。

      这会返回对 m_name 的“只读”引用。

      另请参阅:the C++ FAQ on const correctness

      【讨论】:

        【解决方案4】:

        当你返回string &amp;时,它允许修改类成员......但函数是const,所以不允许这种情况。但是当你返回const string &amp;时,它不允许修改类实例。

        【讨论】:

          【解决方案5】:

          如果你调用A.getName().ModifyTheString() ==> 这意味着你修改了this

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2019-04-20
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-04-29
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多