神奇的多态

来源:互联网 发布:mac怎么设置ppt母版 编辑:程序博客网 时间:2024/05/19 21:41

C++中多态表示通过一个public基类的指针或引用,来得到一个衍生类对象,并希望同一方法根据对象的不同而有不同的行为。一般来说多态需要搭配2种方式来使用:

1、经过隐式转换操作,把衍生类的指针或引用转换为public基类的指针或引用。

如 class A{...};class B:public A{...};

A& a1=b;

2、使用虚函数(virtual function)。

编译器通过在class中扩充一个指向虚函数表的指针来支持动态联编。当然这比起不使用virtual来说无论从空间还是时间来说效率都比较低。

其实还有一种方法可以不使用virtual来实现多态,当然这需要在runtime付出开销。就是使用类型转换。

C++中有四种类型转换符,分别是static_cast、dynamic_cast、reinterpret_cast、和const_cast。

dynamic_cast:动态类型转换,一般用在父类和子类指针或应用的互相转化; 

static_cast:静态类型转换,一般是普通数据类型转换(如int m=static_cast(3.14)); 

reinterpret_cast:重新解释类型转换,很像c的一般类型转换操作; 

const_cast:常量类型转换,是把cosnt或volatile属性去掉。 

就先只谈一下dynamic_cast,它可以用来回答:“是否可以安全的将对象的地址赋给特定类型的指针。如果可以运算符将返回对象的地址,否则将返回一个空指针。通常安全的类型指type或type的衍生类型:dynamic_cast<type*>(*p)。

当然也可以将一个dynamic_cast用于引用,如果失败时,它将抛出bad_cast exception。

哦,还可以使用typeid运算符,它能够确定两个对象是否为同种类型,接受两个参数: 1、类名;

2、结果为对象的表达式。

typeid返回一个对type_info对象的引用,type_info类重载了= =和!=运算符,来对类型进行比较。如果为空指针则抛出bad_typeid exception。

使用type_info和dynamic_cast可以避免virtual。

代码如下:

 

#include <iostream>using namespace std;class A{public:void virtual p(){ cout << "A"<<endl; }void q(){ cout << "Aq" << endl; }};class B :public A{public:void p(){ cout << "B" << endl; }void q(){ cout << "Bq" << endl; }};int main(){B b = B();A a = b;b.p();a.p();A& a1 = b;a1.p();b.q();a.q();a1.q();A* ap = new B();ap->p();ap->q();if (B *bp1 = dynamic_cast<B*>(ap)){bp1->p();bp1->q();}if (typeid(B)==typeid(*ap)){B* bp2=(B*)ap;bp2->p();bp2->q();}delete ap;cin.get();return 0;}
运行情况如下:

与Java不同,在Java中直接使用类名就可以使用多态,而c++却需要指针或引用,原因在于他们并不引发内存中任何“与类型有关的内存委托操作”,受到改变的只是它们所指向的内存的“大小和内容解释方式”。如果直接将一个衍生类对象赋给一个基类对象的话,那将引发切割,衍生类会被切割并塞入基类对象的内存中,多态将消失。

0 0
原创粉丝点击