C++ 将基数*转换为派生*和恒常性

C++ conversion Base* to Derived* and constness

本文关键字:派生 常性 转换 C++      更新时间:2023-10-16

是否总是允许从Base*转换为Derived*?是否始终允许从const Base*转换为const Derived*

我正在使用Qt QSharedPointers。我有一个指向Base对象的 QSharedPointer ,我想将其转换为指向Derived对象的 QSharedPointer 。我事先检查了 pointee 是 Derived 型。

是否有可能 100% 成功的机会

  • static_cast<QSP<Derived>>
  • dynamic_cast<QSP<Derived>>
  • 直接投QSP<Derived>(my_base_pointer)

例如,对于直接转换:

QSP<Derived> inpf = QSP<Derived>(my_base_pointer) ;

我有错误

Error 1 error C2440: 'initializing' : cannot convert from 'Base *' to 'Derived *'

具有 const QSP<Base>my_base_pointer

是因为恒常吗?我应该const_cast在上面吗?我想恒常性不是根本原因,因为如果我

const QSP<Derived> inpf = static_cast<const QSP<Derived>>(my_base_pointer);

发生相同的错误。

您正在为 QSP<Derived> 构造函数提供一个Base*指针,这将不起作用。只要你确定指针确实是一个Derived*你应该能够static_cast它:

QSP<Derived> inpf = QSP<Derived>(static_cast<Derived*>(my_base_pointer)) ;

如果基类至少有一个虚函数,则在这种情况下使用 dynamic_cast 会更安全,因为这是创建基类的目的。如果指针实际上不是指向派生类的指针,您将获得一个 NULL 指针。

你试图做的事情被称为向下投掷。有关详细信息,请查看此答案。

没有从 Base*Derived* 的隐式转换。这是因为指向Base的指针不必指向Derived对象。如果您确定可以,请使用 static_caststatic_cast<Derived*>(base_pointer) 。如果您不确定,并且Base至少有一个虚函数,请使用 dynamic_castdynamic_cast<Derived*>(base_pointer) ;如果指针指向类型为 Derived 的对象,这将执行转换,如果没有,它将返回一个空指针。

正如评论中所建议的,问题是关于QSharedPointer的,Base*转换为Derived*的通用答案不适合这种特殊情况。

深入研究Qt文档,我们发现有趣的成员方法QSharedPointerstaticCast

首先,我想出了这段代码:

QSP<Derived> inpf_filter = my_base_QSP->staticCast<Derived>() ; 

由于我的QSP是指针类型,因此我在上面的调用-> staticCast()不是在QSP上,而是在脚尖上。所以,我又遇到了一个错误:staticCast()不是Base类的成员。我更正为

QSP<Derived> inpf_filter = my_base_QSP.staticCast<Derived>() ; 

这编译了。 QSharedPointer还支持dynamicCast() 。在这种情况下,如果无法执行强制转换,则返回空指针。

QSharedPointer有一整套转换机制:

http://qt-project.org/doc/qt-4.8/qsharedpointer.html#qSharedPointerCast

对于QSharedPointer<U>

QSharedPointer ( const QSharedPointer<T> & other )
QSharedPointer<X>   constCast () const
QSharedPointer<X>   dynamicCast () const
QSharedPointer<X>   objectCast () const
QSharedPointer<X>   staticCast () const

如果构造函数是 U 的子类型,则构造函数有效T

constdynamicstatic演员的作品就像C++的_cast操作员一样。

object做一个qobject_cast.

如果将结果存储在另一个共享指针中,则对共享指针类型执行_cast运算符通常是一个坏主意 - 为了安全地强制转换非侵入式共享指针,您需要执行共享指针感知强制转换。