(C++) 不应该这个 dynamic_cast 检索派生的 class

(C++) should'nt this dynamic_cast retrieve the derived class

阅读 casts in C++ 后,我了解到 dynamic_cast 应该在 "lost" 时检索派生的 class。下面的例子证明我错了。但我完全不明白:

dynamic_cast (B* po = dynamic_cast(&ao);) 的尝试使编译失败,尽管老式的转换将使编译成功,并且 运行 会按预期进行。

//g++  5.4.0
#include <iostream>
using namespace std;

class A{
    protected:
    int x;
    A(int _x) : x(_x) {}
    public:
    A() : x(-1) {}
    void p() { cout << "(A) x = " << x << endl; };
    ~A(){ cout << "destroy A" << endl; }
};

class B : public A{
    public:
    B() : A(-2) {}
    void p() { cout << "(B) x = " << x << endl; };
};

A& f( A& o ) { return o; }

int main()
{
    cout << "start\n";
    {
        B o;
        A ao = f(o);
        ao.p();
        //B* po = dynamic_cast<B*>(&ao); //this fails with following error :
        // source_file.cpp:32:37: error: cannot dynamic_cast ‘& ao’ (of type ‘class A*’) to type ‘class B*’ (source type is not polymorphic)
        B* po = (B*)(&ao);
        po->p();
    }
    cout << "stop\n";
}

//trace
//
//start
//start
//(A) x = -2
//(B) x = -2
//destroy A
//destroy A
//stop

要使 dynamic_cast<> 正常工作,对象需要有一个 vtable。否则,对象中没有指示它属于哪个动态 class。

当且仅当 class 包含至少一个虚拟函数时,才会将 vtable 添加到 C++ class。

因此,向 class 添加至少一个虚函数,动态转换应该可以工作。