如何在c ++中丢弃const

时间:2010-05-26 11:26:23

标签: c++ const

这是我正在尝试做的事情,我不能:

#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。感谢。

5 个答案:

答案 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)

拥有相同功能的constnon-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方法。