【问题标题】:Which methods should be const?哪些方法应该是 const 的?
【发布时间】:2017-02-09 19:06:40
【问题描述】:

const 关键字应该用在类方法上,表示调用对象没有被这个方法修改。但是后者的确切语义是什么?我可以想到三个选项:一个类方法应该是 const 当且仅当

  1. (最弱)它不修改对象存储的位和字节
  2. (更强)它不会修改对象(如 1 中),也不会修改对象拥有的引用对象
  3. (最强)它不会修改对象,也不会修改它引用的任何对象(无论它是否拥有)

什么是“正确”的方式?编程界是否有共识?

例如,标准库的容器 const 语义显然至少满足 2。另一方面,奇怪的是,std::unique_ptr 的 * 运算符甚至不满足 2:它是 const 但返回指向对象的非常量引用,尽管该对象属于 std::unique_ptr 对象根据定义。

另一个例子:

class X
{
private:
    int& intref;

public:
    X(int& intref): intref(intref) {};

    void modifyRef(int& another) const
    {
        this->intref = another;
    }
};

在 2 之后,方法上的 const 没问题,因为 intref 引用了不属于对象的东西。在 3 之后,应该删除 const。

【问题讨论】:

  • "类方法上应使用 const 关键字,表示调用对象未被此方法修改。" -- 错误。表示调用的对象没有被该方法修改。
  • 我会再往下一层,0(logical const-ness) 你在哪里不透明地修改对象状态。
  • @gjha 这不是向下一级,而是横向一步。
  • this->intref = another 不会重新赋值引用,而是赋值给被引用的变量,another 应该按值传递。

标签: c++ methods constants


【解决方案1】:

这三个都不是。

请记住,C++ const 表示逻辑常量,而不是物理常量。

当然,您只能在对象被声明为常量的情况下修改mutable 成员,但除此之外,您只需保留逻辑状态。

那么,你的方法会改变对象的逻辑状态吗?

【讨论】:

  • 我很尴尬地必须承认我不记得 C++ const 表示逻辑常量,因为我以前不知道。但我明白这一点。我想我以前直观地使用过它,然后当我试图设置在方法上使用 const 的规则时感到困惑(这导致了上面的 3 点)。我将进一步阅读有关逻辑常量的信息,任何建议表示赞赏。
  • 类方法上的 const 是不是主要用于公共方法,还是也应该用于私有方法?
  • 如果您始终不正确,它将无法工作。所以,对私有方法也这样做。
  • 哦,是的,对。感谢您提供的提示,以增强我对 C++ 的看法!
【解决方案2】:

Level 0 (Logical const-ness) 允许你不透明地修改对象状态。

考虑一个Cache 类的例子,它有一个 find() 方法,它在本地地图中找到一个元素,在本地地图中找不到它继续搜索 DB.. 等等,最后更新这是具有检索值的本地地图。

Cache 类中的 find() 方法可以是 const,它会为类提供更清晰的接口。类的用户不会被元素检索的内部机制所困扰。

你提供的例子不满足logical const-ness

【讨论】:

    【解决方案3】:

    这是一个很好的参考,可以作为对我的问题的补充,补充其他答案: https://isocpp.org/wiki/faq/const-correctness

    【讨论】:

      猜你喜欢
      • 2017-12-11
      • 2016-02-15
      • 2019-03-17
      • 2016-07-25
      • 2011-06-14
      • 1970-01-01
      • 2020-01-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多