为啥此代码会出现 -fpermissive 错误?

Posted

技术标签:

【中文标题】为啥此代码会出现 -fpermissive 错误?【英文标题】:Why do I get an -fpermissive error with this code?为什么此代码会出现 -fpermissive 错误? 【发布时间】:2012-07-02 23:13:13 【问题描述】:

为什么编译器会在指定的行报错?

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

;

【问题讨论】:

-fpermissive 不是错误,它是控制生成错误的标志。见What does the fpermissive flag do? 【参考方案1】:

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

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

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

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

这篇关于Const Correctness的文章很有意思。

【讨论】:

【参考方案2】:

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

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

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

【讨论】:

关于您的旁注:将字符串作为 const 值返回不允许移动字符串。也就是说,该值将使用 std::string 的复制构造函数而不是移动构造函数,因为您不能将 const string 强制转换为 string&&。

以上是关于为啥此代码会出现 -fpermissive 错误?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 GoogleSignInAccount 会出现此错误?

为啥存储此向量时会出现分段错误?

为啥此代码会导致分段错误错误?

为啥 MySQL 在创建触发器时会出现此错误?

为啥在使用 Python/C API 时会出现此段错误?

为啥在尝试调用采用动态参数的基本构造函数/方法时会出现此编译错误?