将 const T* const 转换为 T*

Posted

技术标签:

【中文标题】将 const T* const 转换为 T*【英文标题】:Convert const T* const to 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 时,你才会有未定义的行为 【参考方案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_;
;

【讨论】:

以上是关于将 const T* const 转换为 T*的主要内容,如果未能解决你的问题,请参考以下文章

将(隐式)提升 shared_ptr<T> 转换为 shared_ptr<const T>

错误 C2440: 'initializing' : 不能从'const mynamespace::mytype*'转换为'const T*'。(示例代

C++的类型转换:static_castdynamic_castreinterpret_cast和const_cast(dynamic_cast还支持交叉转换,const_cast将一个类的con

常量引用 const T&

error C2440: “=”: 无法从“const wchar_t [4]”转换为“LPWSTR”

类型转换