如何丢弃 c++ 中的 const

发布于 2024-09-03 08:40:54 字数 443 浏览 5 评论 0原文

这就是我想要做的,但我不能:

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

This is what I'm trying to do and I can't:

#include <string>
using namespace std;
class A {
public:
  bool has() const { return get().length(); }
  string& get() { /* huge code here */ return s; }
private:
  string s;
};

The error I'm getting is:

passing ‘const A’ as ‘this’ argument of
‘std::string& A::get()’ discards qualifiers

I understand what the problem is, but how can I fix it? I really need has() to be const. Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

葬﹪忆之殇 2024-09-10 08:40:54

添加 get() 的第二个重载:

string const & get() const { return s; }

它将在 A 类的 const 类型对象上调用。

在实践中,我更喜欢仅添加 const 类型的访问器,然后将修改完全保留在类内部,甚至完全避免它们。例如,这意味着让方法 DoUpdateLabel(){/* 对 s*/} 执行某些操作,而不是暴露内部结构。这有一个很好的副作用,即在许多情况下您可以避免重复访问器。

如果您绝对必须通过访问器进行修改,并且您也不想要额外的 const 包装器,则可以使用 const_cast<>

bool has() const { return const_cast<A*>(this)->get().length(); }

但是,如果 get() 有一侧-effects 和 has() 被声明为 const,这是否是您真正想要的行为是值得怀疑的。

Add a second overload of get():

string const & get() const { return s; }

That will be called on a const typed object of class A.

In practice, I prefer adding only const-typed accessors, and then keeping modifications entirely internal to the class or even avoid them entirely. For example, that means having a method DoUpdateLabel(){/*do something with s*/} rather than expose the internals. That has the nice side effect that you can avoid duplicating accessors in many cases.

If you absolutely must have modification via accessors and you also don't want an extra const wrapper, you can use const_cast<>:

bool has() const { return const_cast<A*>(this)->get().length(); }

However, if get() has side-effects and has() is declared const, it's questionable whether this is behavior you really want.

妳是的陽光 2024-09-10 08:40:54

我认为你的问题有点模糊。

您有:

bool has() const { return get().length(); }
string& get() { /* huge code here */ return s; }

...并且需要 has()const

我可以想出三种方法来解决这个问题,具体取决于您实际想要做什么:

最干净的选择是 has 仅使用 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;
};

I think your question is a bit vague.

You have:

bool has() const { return get().length(); }
string& get() { /* huge code here */ return s; }

... and need has() to be const.

I can think of three ways to get around this, depending on what you're actually trying to do:

The cleanest option would be for has to only use const code. If some of your /* huge code here */ code non-const but doesn't actually change the logical value of the class (like computing a cached internal value) consider using mutable on the data involved.

If the /* huge code here */ part is non-const by nature, consider refactoring it into a different function and calling it separately:

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

Ultimately, you can also cast the const-ness away (but keep in mind that the need to do so is almost always a sign of bad design/need to refactor):

class A {
public:
  bool has() const { return const_cast<A*>(this)->get().length(); }
  string& get() { /* huge code here */ return s; }
private:
  string s;
};
北渚 2024-09-10 08:40:54

相同函数有 const非 const 版本是很常见的。

因此,如果您的对象作为 const 对象调用,则将调用其中一个,如果 非 const 对象发生同样的情况,则将调用第二个。

我不得不提的是,这种技术通常与操作员一起使用,但也适合您当前的情况。


另外,在您当前的情况下,最好的方法可能意味着只有 const 方法,例如

const string& get() const { return s }

并重构所有其他代码,以便它可以使用通过常量引用返回的字符串。

It's pretty usual to have const and non-const versions of the same functions.

So, one of them would be called if your object is called as a const object, and the second - if the same happens with a non-const.

I have to mention, that this technique usually is used with operators but is also suitable for you current case.


Also, in your current case the best approach could mean having ONLY const method like

const string& get() const { return s }

and refactoring all your other code so it works with a string returned via constant reference.

謌踐踏愛綪 2024-09-10 08:40:54
std::string get() const { return s; }

因为按值传递字符串通常很便宜(我不记得这是否是一个保证),而且我认为您不希望您正在查看的字符串在 A 修改它时在您脚下发生变化。

std::string get() const { return s; }

because passing strings by value is usually cheap (I don't remember if this is a guarantee), and I don't think you want the string you're looking at to change under your feet when A modifies it.

凡间太子 2024-09-10 08:40:54

试试这个:

const string& get() const { return s; }

第一个 const 适用于方法 get() 的返回类型。返回类型是对字符串的引用。总而言之,它是对字符串的 const 引用,这强制不更改此 returb 值。

第二个 const 适用于该方法,有效地使其成为 const 方法。

Try this:

const string& get() const { return s; }

The first const applies to the return type of the method get(). The return type is a reference to a string. Altogether it's a const reference to a string, which enforces that this returb value is not to be changed.

The second const applies to the method, effectively making it a const method.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文