在C ++中,如何在不使用dynamic_cast的情况下将子类实例从一个基类指针转换为另一个基类指针?

时间:2015-11-16 08:46:31

标签: c++ types casting

我想在没有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类型的指针,如何在没有ClassB的情况下将其转换为dynamic_cast

3 个答案:

答案 0 :(得分:5)

AB是不相关的类型,因此您无法在它们之间进行投射。只要您某些 pClassA指向C,您就可以对C*进行中间转换,然后依赖隐式派生到基础转换到B*

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

或者您可以明确地将C*强制转换为B*

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

答案 1 :(得分:4)

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

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();

- 有效实施更有效的动态投射方式。

答案 2 :(得分:1)

您可以使用某些演员阵容将pClassA投射到B*,包括reinterpret_cast和C风格演员阵容。

你真正的问题是&#34;如何在没有dynamic_cast的情况下安全地 。好吧,虽然你可以做各种对象验证机制,但我怀疑你真的需要它们。

dynamic_cast出了什么问题?

<强> 编辑: 嗯。我更喜欢Idiomatic 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