c++ - 为什么不对指针强制执行 constness?

标签 c++ pointers constants transitive-const

考虑以下代码片段:

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::vectorstd::string。后者的示例包括 std::spanstd::unique_ptrstd::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/

相关文章:

c++ - 文本宽度计算模块

getter 的 c++ const 正确性问题

c++ - 在 Delphi 应用程序中使用 C++ DLL 回调函数

c - 在使用链表实现Stack的过程中出现Segmentation错误

c++ - Windows C++ 单元测试 : testing dll-exported class

c++ - 是否可以交换结构数组(线性时间)?

c - 了解 return 语句之前的 free() 缓冲区

typescript - 为什么我们不能在 TypeScript 类中定义一个 const 字段,为什么 static readonly 不起作用?

c++ - 通过指针更改 const 的值

c - 无内存重复的可内联常量 C 数组