这是我正在尝试做的事情,我不能:
#include <string>
using namespace std;
class A {
public:
bool has() const { return get().length(); }
string& get() { /* huge code here */ return s; }
private:
string s;
};
我得到的错误是:
passing ‘const A’ as ‘this’ argument of
‘std::string& A::get()’ discards qualifiers
我明白问题所在,但我该如何解决?我真的需要has()
成为const
。感谢。
答案 0 :(得分:6)
添加get()
的第二次重载:
string const & get() const { return s; }
将在类const
的{{1}}类型对象上调用。
在实践中,我更喜欢只添加 A
类型的访问器,然后将修改完全保留在类内部,甚至完全避免它们。例如,这意味着使用方法const
而不是暴露内部。这有很好的副作用,你可以避免在许多情况下重复访问器。
如果您绝对必须通过访问者进行修改,并且您也不需要额外的const包装器,则可以使用DoUpdateLabel(){/*do something with s*/}
:
const_cast<>
但是,如果bool has() const { return const_cast<A*>(this)->get().length(); }
有副作用且get()
被声明为has()
,那么这是否是您真正想要的行为是值得怀疑的。
答案 1 :(得分:2)
拥有相同功能的const
和non-const
版本通常很常见。
因此,如果您的对象被称为const
对象,则会调用其中一个,如果non-const
调用该对象,则会调用其中一个。
我必须提一下,这种技术通常与运营商一起使用,但也适合你当前的情况。
此外,在您目前的情况下,最佳方法可能意味着只有const
方法,如
const string& get() const { return s }
并重构所有其他代码,以便它可以使用通过常量引用返回的字符串。
答案 2 :(得分:2)
我认为你的问题有点模糊。
你有:
bool has() const { return get().length(); }
string& get() { /* huge code here */ return s; }
...并且需要has()
为const
。
我可以想出三种方法来解决这个问题,具体取决于你实际上要做的事情:
最干净的选择是has
仅使用const
代码。如果您的某些/* huge code here */
代码非const但实际上并未更改类的逻辑值(如计算缓存的内部值)请考虑对所涉及的数据使用mutable
如果/* huge code here */
部分本质上是非const的,会考虑将其重构为不同的函数并单独调用它:
using namespace std;
class A {
public:
bool has() const { return get().length(); }
const string& get() const { return s; }
void computestuff() { /* huge code here */ }
private:
string s;
};
A instance;
// old client code:
// string s = instance.get();
//
// new code:
instance.computestuff(); // non-const call
instance.get(); // const call
instance.has(); // const call
最终,你也可以抛弃常数(但请记住,这样做的必要性几乎总是表明设计糟糕/需要重构):
class A {
public:
bool has() const { return const_cast<A*>(this)->get().length(); }
string& get() { /* huge code here */ return s; }
private:
string s;
};
答案 3 :(得分:0)
std::string get() const { return s; }
因为按值传递字符串通常很便宜(我不记得这是否是一种保证),而且当A修改它时,我认为你不希望你正在寻找的字符串在你的脚下改变。 / p>
答案 4 :(得分:0)
试试这个:
const string& get() const { return s; }
第一个const适用于方法get()的返回类型。返回类型是对字符串的引用。总而言之,它是对字符串的const引用,强制执行此返回值不会被更改。
第二个const适用于该方法,有效地使其成为const方法。