为什么我会收到此代码的 -fallowive 错误

Why do I get an -fpermissive error with this code?

本文关键字:代码 -fallowive 错误 为什么      更新时间:2023-10-16

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

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
};

您需要声明函数Get()const

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

即使Get()不会更改任何成员值,编译器也会被指示只允许您调用显式标记为 const 的函数。

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

这篇关于常量正确性的文章非常有趣。

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

要么使c非常量(如注释掉的代码版本),要么使Get常量。由您决定哪种方法是正确的,但看起来您应该采用后者。

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