为什么我用这段代码得到了一个错误的错误?

时间:2012-07-02 23:13:13

标签: c++ compiler-errors

为什么编译器会在指定的行上抱怨?

class C
{
    std::string s;
public:
    C() { s = "<not set>";}
    ~C() {}
    void Set(const std::string ss) { s=ss; }
    const std::string Get() { return s; }

    C &operator=(const C &c) { Set(c.Get()); return *this; }
    //error: passing ‘const C’ as ‘this’ argument of ‘const string C::Get()’
    // discards qualifiers [-fpermissive]


    //C &operator=(C &c) { Set(c.Get()); return *this; }   <-- works fine

};

2 个答案:

答案 0 :(得分:5)

您需要将函数Get()声明为const

const std::string Get() const { return s; }

即使Get()未更改任何成员值,也会指示编译器仅允许您调用明确标记为const的函数。

gcc通过使用参数-fpermissive指示您可以覆盖它的投诉;但是,通常最好不要这样做(或者为什么要声明任何const?)。通常,最好确保在const参数上调用的每个成员函数都是const成员函数。

关于Const Correctness的这篇文章非常有趣。

答案 1 :(得分:3)

operator =对象c内部是一个常量对象:它具有const C类型。在C ++语言中,不允许调用常量对象的非常量成员函数。即调用c.Get()是非法的,因为Get是非常量成员函数。这就是编译器报告错误的原因。

使您的c非常数(如在您已注释掉的代码版本中),或使Get保持不变。由你决定哪种方法是正确的,但看起来你应该做后者。

作为旁注,将Get()声明为返回const std::string没有多大意义。如果您通过引用(const std::string &)返回它,那么const将是合适的。但是,由于您按值返回,因此将返回类型声明为const并不是很有用。这是你个人风格的问题。