为啥此代码会出现 -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 &
),那么const
将是合适的。但是由于您是按值返回,因此将返回类型声明为 const
并没有那么有用。不过,这取决于您的个人风格。
【讨论】:
关于您的旁注:将字符串作为 const 值返回不允许移动字符串。也就是说,该值将使用 std::string 的复制构造函数而不是移动构造函数,因为您不能将 const string 强制转换为 string&&。以上是关于为啥此代码会出现 -fpermissive 错误?的主要内容,如果未能解决你的问题,请参考以下文章