c++ - c+ +'s ` const` promise 有什么好处?

标签 c++ constants

我试图更深入地理解 c++ 的 const 语义,但我无法完全理解 constness 保证的真正值(value)。 正如我所见,constness 保证不会发生突变,但请考虑以下(人为的)示例:

#include <iostream>
#include <optional>
#include <memory>

class A {
public:
  int i{0};

  void foo() {
    i = 42;
  };
};

class B {
public:
  A *a1;
  A a2;

  B() {
    a1 = &a2;
  }

  void bar() const {
    a1->foo();
  }
};

int main() {
  B b;
  std::cout << b.a2.i << std::endl; // output is 0

  b.bar();

  std::cout << b.a2.i << std::endl; // output is 42
}

因为 barconst,所以人们会假设它不会改变对象 b。但是在它被调用之后 b 发生了变化。 如果我这样写方法 foo

void bar() const {
    a2.foo();
}

然后编译器会按预期捕获它。 因此,似乎可以很容易地用指针绕过编译器。我想我的主要问题是,我如何或是否可以 100% 确定 const 方法不会对调用它们的对象造成任何突变?还是我对 const 有完全错误的期望?

为什么 c++ 允许在 const 方法中通过指针调用非常量方法?

编辑:

感谢 Galik 的评论,我现在发现了这个:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4372.html

嗯,这正是我要找的!谢谢! 而且我发现 Yakk 的回答也很有帮助,所以我会接受他的回答。

最佳答案

const 告诉调用者“这不应该改变对象”。

const 帮助实现者解决一些错误,在这些错误中,意外改变状态会产生错误,除非实现者将其丢弃。

const 数据(不是引用,实际数据)向编译器保证任何修改此数据的人都在做未定义的行为;因此,编译器可以自由假设数据从未被修改。

std 库中的const 对线程安全做了一定的保证。

所有这些都是 const 的使用。


如果一个对象不是const,任何人都可以自由地const_cast离开const对象的引用并修改它。

如果对象是 const,编译器将无法可靠地诊断出您是否丢弃了 const,并生成了未定义的行为。

如果您将数据标记为 mutable,即使它也被标记为 const 也不会。

std 提供的基于 const 的保证受限于您按照这些保证依次传递给 std 的类型。


const 不会强制给程序员太多。它只是试图提供帮助。

没有任何一种语言可以使恶意程序员变得友好; C++ 中的 const 不会尝试。相反,它试图使编写 const 正确代码比编写 const 错误代码更容易

关于c++ - c+ +'s ` const` promise 有什么好处?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49286402/

相关文章:

c++ - 将 C 风格的 pretty-print 重构为 C++ 风格的 pretty-print

c++ - 模板特化和实例化

c++ - C++ 中 !cin 的含义是什么?

删除 R 中的常量列

c++ - const int*、const int * const 和 int const * 有什么区别?

javascript - 使用 Object.values() 方法分配常量数组?

c++ - 指向基类和私有(private)继承的指针

c++ - 如何使用 C++ 上的引用删除对象

C题: (const void *) vs (void *)

c++ - QT & C++ : Passing 'const QString' discards qualifiers