考虑以下代码片段:
class A
{
public:
void nonConstFun()
{
}
};
class B
{
private:
A a_;
A * pA_;
public:
void fun() const
{
pA_->nonConstFun();
//a_.nonConstFun(); // Gives const related error
}
};
int main()
{
B b;
b.fun();
}
在这里,我希望编译器会因为在 B::fun()
内调用 A::nonConstFun()
的常量而失败,而不管类型如何一个对象。
但是编译器会提示对象,而不是指针。为什么? 我在 Windows 10 上使用 VS2017。
最佳答案
其他答案解释了 T* const
vs T const *
正在发生的事情。但重要的是要理解这不仅仅是语法的含义。
当您在结构内有 T*
时,指针位于对象内部(对象布局的一部分),但指向的对象在物理上位于结构外部。这就是为什么带有 T*
成员的 const 对象不允许修改指针,但允许修改指向的对象 - 因为物理上指向的对象在封闭对象之外。
并且由程序员决定指向的对象是逻辑上封闭对象的一部分(因此应该与封闭对象共享常量)还是逻辑上是外部实体。前者的示例包括 std::vector
、std::string
。后者的示例包括 std::span
、std::unique_ptr
、std::shared_ptr
。如您所见,两种设计都很有用。
C++ 的缺点是它没有提供一种简单的方法来表达如上所述的逻辑常量(您对代码的实际期望)。
这是已知的,为了这个确切的目的,有一个尚未标准的实验类propagate_const
std::experimental::propagate_const is a const-propagating wrapper for pointers and pointer-like objects. It treats the wrapped pointer as a pointer to const when accessed through a const access path, hence the name.
struct B
{
A a_;
std::experimental::propagate_const<A *> pA_;
void fun()
{
pA_->nonConstFun(); // OK
}
void fun() const
{
// pA_->nonConstFun(); // compilation error
}
};
关于c++ - 为什么不对指针强制执行 constness?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52607625/