考虑以下代码:
#include <iostream>
using namespace std;
class Base{
int i;
public:
virtual bool baseTrue() {return true;}
Base(int i) {this->i=i;}
int get_i() {return i;}
};
class Derived : public Base{
int j;
public:
Derived(int i,int j) : Base(i) {this->j=j;}
int get_j() {return j;}
};
int main()
{
Base *bp;
Derived *pd,DOb(5,10);
bp = &DOb;
//We are trying to cast base class pointer to derived class pointer
cout << bp->get_i() << endl;
cout << ((Derived *)bp)->get_j() << endl;**//HERE1**
pd=dynamic_cast<Derived*> (bp); **//HERE2**
// If base class is not polymorphic
//throw error
//error: cannot dynamic_cast `bp' (of type `class Base*') to
//type `class Derived*' (source type is not polymorphic)
cout << pd->get_j() << endl;**//HERE2**
//Now we try to cast derived Class Pointer to base Class Pointer
Base *pb;
Derived *dp,Dbo(50,100);
dp = &Dbo;
cout << ((Base *)dp)->get_i() << endl;**//HERE3**
//cout << ((Base *)dp)->get_j() << endl;
//throws error Test.cpp:42: error: 'class Base' has no member named 'get_j'
pb = dynamic_cast<Base * > (dp); **//HERE4**
cout << pb->get_i() << endl; **//HERE4**
//cout << pb->get_j() << endl;
//throws error Test.cpp:47: error: 'class Base' has no member named 'get_j'
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出
Gaurav@Gaurav-PC /cygdrive/d/Glaswegian/CPP/Test
$ ./Test
5
10
10
50
50
Run Code Online (Sandbox Code Playgroud)
我的投射方式(Line HERE1和HERE2)和(HERE3&HERE4),这两者有什么区别?两者都产生相同的输出,那么为什么要选择dynamic_cast
dynamic_cast 是"安全的",因为它会抛出一个异常,或者在你做"坏"的事情时返回NULL(或者,正如Nawaz所说,它不会编译,因为类型足够糟糕,编译器可以看到它出错)
的(Derived *)...形式将作用类似reinterpret_cast<Derived *>(...),这是"不安全" -它将一个指针简单地转换为其它指针类型,是否能产生一个有意义的结果或没有.如果表现"糟糕",那就是你的问题.
你可以这样做:
int x = 4711;
Derived *dp = (Derived *)x;
cout << dp->get_j();
Run Code Online (Sandbox Code Playgroud)
编译器可能会对整数的大小抱怨,但否则,它会编译代码.它很可能根本不会运行,但如果确实如此,结果可能没什么"有用".