为什么编译器会在指定的行上抱怨?
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
};
答案 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
并不是很有用。这是你个人风格的问题。