【问题标题】:Convert const T* const to T*将 const T* const 转换为 T*
【发布时间】:2014-03-28 11:59:23
【问题描述】:

是否可以在 C++ 中进行这种类型的转换?
需要以这种方式声明我的属性。

Class A {
public:
  void update() { ++i_; }
private:
  int i_;  
}

Class B{
public:
   void foo() {
       a_->update(); /* Error */
   }
private:
 const A* const a_;
}

错误是:

将“const A”作为“void A::update()”的“this”参数传递会丢弃 限定符 [-fpermissive]

我尝试使用 static_cast,但还不够……不起作用……有什么想法吗?

【问题讨论】:

  • 正如您在答案中看到的,您需要更改您的设计。您有一个指向const 的指针,因此在对象上调用非const 方法的唯一方法是const_cast。但是你修改对象(++i)所以这是未定义的行为。即使现在有效,明天也不会有效。 改变你的设计.
  • @iavr: 等一下const_cast 不一定表示未定义的行为;只有当指向的对象首先被创建 const 时,你才会有未定义的行为

标签: c++ pointers casting


【解决方案1】:

这里有两个选择。要么使 A::update 成为 const 函数-

Class A {
  void update() const;
}

或者去掉指针的常量。

Class B{
public:
   void foo() {
       const_cast<A*>(a_)->update();
   }
private:
 const A* const a_;
}

前者将是首选方法,但这也会阻止您在 A 类的更新中做任何有用的事情。

根据经验,如果你必须将 const 去掉,那么你真的很想看看为什么指针首先是 const。

【讨论】:

    【解决方案2】:

    禁止在非常量方法中使用 const 成员(除非使用 mutable)。在声明foo()update() 之后添加const

    void update() const { ...  }
                  ^^^^^
    
    void foo() const { ... }
               ^^^^^
    

    或者...

    如果你不想把update变成const,你可以使用const_cast

    void foo() const // Now, this const keyword is optional but recommanded
    {
       const_cast<A*>(a_)->update();
       ^^^^^^^^^^^^^^
    }
    

    【讨论】:

      【解决方案3】:

      假设您不能将方法声明为 const 并且您知道自己在做什么 (tm) 以及为什么这样做不好:试试 const_cast

      【讨论】:

        【解决方案4】:

        * 后面的 const 与它无关。您必须将使用 a_ 的函数声明为 const 函数。如果它们不编译,则必须在调用之前使用 const_cast 或 reinterpret_cast 从指针中删除 const。但是这是非常狡猾的,如果 update() 函数修改了最初声明为 const 的对象,这是未定义的行为。

        【讨论】:

          【解决方案5】:

          你有几个选择:

          • 使用const_cast 丢弃 const 并调用方法。

          • 使update成为一个const方法,这样就可以通过一个const指针来调用它。

          • 首先不要将a_ 存储为常量。改成A* const a_,这样就可以调用非常量方法了,但是指针不能改。

          【讨论】:

            【解决方案6】:

            你得到的错误

            将“const A”作为“void A::update()”的“this”参数传递会丢弃 限定符 [-fpermissive]

            是在 const 指针上调用 non-const 方法的结果。这是禁止的。由于您需要更新为non-const,并且您不能存储指向non_const A 的指针,因此您可以使用运算符const_cast 来抛弃const,这是如何做到的:

            class A {
            public:
              void update(){}
            };
            
            class B{
            public:
               void foo() {
                   const_cast< A*>(a_)->update(); /* OK*/
               }
            private:
             const A* const a_;
            };
            

            但是,您应该重新考虑您的设计。

            【讨论】:

              【解决方案7】:

              正如之前有人提到的,使用 mutable/const 但这会稍微改变您的设计:

              class A {
              public:
                  void update() const { ++i_; } // this will make the method callable by const A*
              private:
                  mutable int i_;  // and this will make you field mutable in a const method
              };
              
              class B{
              public:
                  void foo() {
                     a_->update(); 
                  }
              private:
                  const A* const a_;
              };
              

              【讨论】:

                猜你喜欢
                • 2016-02-13
                • 1970-01-01
                • 2011-01-18
                • 2013-10-20
                • 1970-01-01
                • 1970-01-01
                • 2020-10-17
                • 1970-01-01
                • 2021-06-11
                相关资源
                最近更新 更多