在C++中,如果没有dynamic_cast,我怎么能将一个子类实例从一个基类指针转换到另一个基类

In C++ how could I cast a sub class instance from one base class pointer to another without dynamic_cast?

本文关键字:一个 基类 C++ 实例 指针 转换 另一个 子类 怎么能 dynamic 如果没有      更新时间:2023-10-16

我想在没有dynamic_cast:的情况下完成此操作

class A {};
class B {};
class C : public A, public B {};
void func()
{
    A* pClassA = new C();
    B* pClassB = what_cast<B*>(pClassA); // what could the cast be?
}

我认为ClassC类型的实例可以表示为ClassAClassB。现在,如果我只能得到类型为ClassA的指针,那么在没有dynamic_cast的情况下,我如何将其转换为ClassB

AB是不相关的类型,因此不能在它们之间进行强制转换。只要确定pClassA指向C,就可以对C*进行中间转换,然后依靠隐式派生到基的转换来获得B*:

B* pClassB = static_cast<C*>(pClassA);

或者,您可以通过C*显式强制转换为B*:

B* pClassB = static_cast<B*>(static_cast<C*>(pClassA));

在设计良好的代码中,这种类型的问题几乎不会发生。所以,最好重新考虑你的设计。也许你想避免多态性,当你真的应该使用它的时候?你可以

struct B; // forward decl
struct A {
  virtual B*this_as_B_ptr() { return nullptr; }
  const B*this_as_B_ptr() const { return const_cast<A*>(this)->this_as_B_ptr(); }
  virtual~A() {}
};
struct B { /* ... */ }; // may be in different header
struct C:A,B            // may be in yet different header
{
  B*this_as_B_ptr() override { return this; }
};
A* pA = new C;
B* pB = pA->this_as_B_ptr();

--有效地实现了更高效的动态铸造方式。

您可以使用一些强制转换将pClassA强制转换为B*,包括reinterpret_cast和C样式强制转换。

你真正的问题是"在没有dynamic_cast的情况下,我如何安全地投射。好吧,尽管你可以做所有类型的对象验证机制,但我怀疑你是否真的需要它们。

dynamic_cast出了什么问题?

编辑: 嗯。我更喜欢习语C++而不是技巧,但有时你确实需要原始大小/速度。我会选择一些标记机制:

enum Types{AType,BType,CType};
struct A {
    int type;
A(): type(AType) {}
bool is (Types wantedType) {return (type & wantedType) == wantedType; }
};
struct B {
};
struct C : public A, public B {
    C(){ type = (type | CType) | BType ; }
};

通过这种方式,您可以静态地询问对象是否来自类型Types

实际运行:http://coliru.stacked-crooked.com/a/1774f9c85603fa31

相关文章: