我试图更深入地理解 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
}
因为 bar
是 const
,所以人们会假设它不会改变对象 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/