(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 添加至少一个虚函数,动态转换应该可以工作。
阅读 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 添加至少一个虚函数,动态转换应该可以工作。