C++ safe alternative to dynamic_cast

teo*_*ron 2 c++ casting

In what scenarios can be reinterpret_cast used to cast from a base pointer that's actually a derived instance pointer? (via polymorphism).

Static casts do not work if the inheritance is polymorphic.

I considered this trivial scenario:

class A
{
public:
    virtual void Hello()
    {
        cout<<" A ";
    }
    virtual int GetType() { return 1; }
};

class B: public A
{
public:
    void Hello()
    {
        cout<< " B ";
    }
    void Do()
    {
        cout << " Another method of B";
    }
    int GetType() { return 2;}
};

/// ... sample/test code
A* a1 = new A();
A* b1 = new B();
A* a2;
B* b2;

if (a1->GetType() == 1)
{
    a2 = a1;
    a2->Hello();
}
else
if (a1->GetType() == 2)
{
    b2 = reinterpret_cast<B*>(a1);
    b2->Do();
    b2->Hello();
}
Run Code Online (Sandbox Code Playgroud)

心里很天真"伪类型识别方法GetType()),我用来决定我是否可以转换它们.它是完全错误的使用reinterpret_casts可言,这样的目的,避免dynamic_casts的?(即它是一个paranoic设计,内在的危险而不太灵活,可以引入不必要的麻烦?也许它是安全的,值得进行正常的动态注塑小的性能成本是多少?我知道,多重继承和/或虚拟继承会搞乱其他任何转换操作,除了多态/动态的).

Che*_*Alf 6

你不能reinterpret_cast安全地使用垂头丧气.但你可以使用

  • static_cast,当你知道该对象的动态类型(可能源自)你投下去的一个,和

  • dynamic_cast,如果静态已知类是多态的,则为引用或指针.

在另一个方向上,对于向上转换,您可以(但不应该)使用C样式转换以转换为无法访问的基础.它在标准中得到特别支持.但我从未找到过使用它的机会.

  • @KerrekSB:小心翼翼地,您可以使用`reinterpret_cast`在两个标准布局类之间进行向下转换.但你真的,真的不应该. (2认同)

Ker*_* SB 5

只回答你的第一句话:从不。

基指针静态转换为更多派生指针的唯一有效方法是使用 a static_cast,并且仅当基为非虚拟时才有效:

Base * b = &derived;                       // implicit Derived * => Base *

Derived * p = static_cast<Derived *>(b);   // OK, I know what *b really is
Run Code Online (Sandbox Code Playgroud)

静态转换应该被认为是隐式转换的对立面。

Areinterpret_cast是完全错误的。(唯一通常可以接受的重新解释转换是为了 I/O 的目的而对字符指针进行转换。)

(当您有一个指向虚拟基的指针时,您别无选择,只能使用 a dynamic_cast,但这当然是因为在这种情况下基子对象仅在运行时确定。)

  • @teodron:可能与彼此一样昂贵,但唯一可以确定的方法是对其进行测量。 (2认同)
  • @teodron:您可能担心错误的事情。如果您已经有一个虚拟基础并准备好处理它的运行时成本,则 dynamic_cast(您是否真的需要强制转换!)应该不成问题。“虚拟”的意思是“我会在运行时告诉你”,如果这就是你需要的,你必须为此付费。我会更担心首先需要演员的设计。那似乎没有必要。 (2认同)