将 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