代码之家  ›  专栏  ›  技术社区  ›  Arun

为什么指针不强制执行常量?

  •  23
  • Arun  · 技术社区  · 6 年前

    请考虑以下代码段:

    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();
    }
    

    在这里,我期望编译器由于调用的常量不足而导致编译失败 A::nonConstFun() B::fun() 不考虑对象的类型。

    但是,编译器会为对象而不是指针而抱怨。为什么? 我正在Windows 10上使用VS2017。

    2 回复  |  直到 6 年前
        1
  •  43
  •   Lightness Races in Orbit    6 年前

    强制执行。

    如果您尝试更改指针,编译器将不允许您更改。

    记得, T* const T const*

    你可以通过两种方法来保护它 A const*

        2
  •  55
  •   bolov    4 年前

    其他答案解释了 T* const T const * 这就是正在发生的事情。但重要的是要理解这不仅仅是语法的含义。

    当你有一个 T* 在结构内部,指针位于对象内部(对象布局的一部分),但指向的对象实际上位于结构外部。这就是为什么常量对象 成员不允许修改指针,但允许修改指向的对象-因为指向的对象在物理上位于封闭对象的外部。

    封闭对象的一部分(因此应该与封闭对象共享常量),或者它在逻辑上是一个外部实体。前者的例子包括 std::vector , std::string . 后者的例子包括 std::span , std::unique_ptr , std::shared_ptr . 如你所见,这两种设计都很有用。

    C++的缺点是它没有提供一种简单的方式来表达逻辑上的一致性(如上所述(您实际从代码中得到了什么)。

    这是众所周知的,为了这个确切的目的,有一个实验班,这是尚未标准 propagate_const

    std::experimental::propagate \u const是的const传播包装器 指针和类似指针的对象。它将包装的指针视为 通过常量访问路径访问时指向常量的指针,因此 姓名。

    struct B
    {
        A a_;
        std::experimental::propagate_const<A *> pA_;
    
       void fun()
        {
            pA_->nonConstFun(); // OK
        }
        void fun() const
        {
            // pA_->nonConstFun(); // compilation error
        }
    };