父类指针无法直接调用子类的新函数,需要转换为子类的指针后方可调用。
C++编译器在编译的时候是做静态类型分析。也就是说,你的父类指针是否真的指向一个子类类型,编译器并不会做这个假设。所以你用父类指针去调用子类的函数是无法被识别的。这里提供一种不安全和一种安全的转换方式可以实现该功能:
假设我们有父类和子类的定义如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
class
Base
{
public
:
void
virtual
Func()
{
cout <<
"Base\n"
;
}
};
class
Derived :
public
Base
{
public
:
void
Func()
{
cout <<
"Derived\n"
;
}
void
NewFunc()
{
cout <<
"New func\n"
;
}
};
|
1. 强制转换(不安全)
1
2
3
4
5
6
|
Base* b =
new
Derived();
b->Func();
// 不安全的转换
Derived* d = (Derived*)b;
d->NewFunc();
|
这里之所以说不安全是因为转换的时候无法得知是否转换成功。编译器强制把d当成Derived类型去使用。比如说b本来是真的指向Base而不是Derived类型那么强制转换后调用Derived的NewFunc可能会导致程序崩溃。
2.动态转换,dynamic_cast(安全)
1
2
3
4
5
6
7
8
|
Base* b =
new
Derived();
b->Func();
// 安全转换
Derived* d =
dynamic_cast
<Derived*>(b);
if
(d != NULL)
{
d->NewFunc();
}
|
dynamic_cast是在运行时去做转换而非编译时,所以它可以给出是否转换成功的信息。如果转换不成功则返回NULL。所以可以判断转换结果是否为NULL来决定是否能使用该指针不会导致程序崩溃
dynamic_cast参考: