C++中的多态根据实际的对象类型调用对应的函数
(1)可以在基类中定义虚函数返回具体的类型信息
(2)所有的派生类都必须实现类型相关的虚函数
(3)每个类中的类型虚函数都需要不同的实现
使用虚函数进行动态类型识别的缺陷
(1)必须从基类开始提供类型虚函数
(2)所有派生类都必须重写类型虚函数
(3)每个派生类的ID必须唯一
示例代码:
#include using namespace std;class Parent
{
private:int a;
public:enum {ID = 0};virtual int getID(){return ID; }
};class Child : public Parent
{
public:enum {ID = 1};int array[102400];virtual int getID(){return ID;}};void f(Parent *p)
{//Child *c = (Child *)p; //派生类指针指向基类对象 //如果指针指向派生类对象,可以转换,指向基类对象,不能转换if (p->getID() == Child::ID) //如果成立,说明指向派生类对象{Child *c = (Child *)p;c->array[102400 - 1] = 100;}else{cout << "不能转换" << endl;}
}int main()
{//Parent *p = new Child;Parent *p = new Parent;f(p);return 0;
}
运行结果:
新的关键字 dynamic_cast
(1)dynamic_cast是C++中的新型关键字
(2)dynamic_cast用于基类和派生类之间的转换
(3)dynamic_cast要求使用的目标类型是多态的
即要求所在类族至少有一个虚函数
用于指针转换时,转换失败返回空指针
用于引用转换时,转换失败将引发bad_cast异常
dynamic_cast的优势
(1)不用显示的声明和定义虚函数
(2)不用为类族中的每个类分配类型ID
dynamic_cast的缺陷
只能用于有虚函数的类族
示例代码:
#include using namespace std;class Parent
{
private:int a;
public:virtual void show(){}
};class Child : public Parent
{
public:int array[102400];void show(){}
};void f(Parent *p)
{Child *c = dynamic_cast(p); //如果p指向的是基类对象,则转换失败,转换失败返回NULLif (NULL == c){cout << "转换失败" << endl;}else{cout << "转换成功" << endl;c->array[102400 - 1] = 100;}
}int main()
{//Parent *p = new Child;Parent *p = new Parent;f(p);return 0;
}
运行结果:
示例代码:
#include
#include using namespace std;class Parent
{
private:int a;
public:virtual void show(){}
};class Child : public Parent
{
public:int array[102400];
public:void show(){}
};void f(Parent *p)
{if (typeid(*p) == typeid(Child)){cout << "可以转换" << endl;Child *c = (Child *)p; //派生类指针指向基类对象c->array[102400 - 1] = 100;}else if (typeid(*p) == typeid(Parent)){cout << "不能转换" << endl;}
}int main()
{int a;char ch;Parent p1;Child c1;const type_info &pa = typeid(a); const type_info &pch = typeid(ch); const type_info &pp1 = typeid(p1); const type_info &pc1 = typeid(c1); cout << pa.name() << endl;cout << pch.name() << endl;cout << pp1.name() << endl;cout << pc1.name() << endl;//if (pa.name() == i) // 不同编译器可以不一样(不能这么写)Parent *p = new Parent;//Parent *p = new Child;f(p);return 0;
}
运行结果:
示例代码:
#include using namespace std;class Parent //含有纯虚函数的类称为抽象类 抽象类不能创建对象
{
public:void show(){cout << "this is parent" << endl;}virtual void print() = 0; //纯虚函数 没有函数体
};class Child : public Parent
{
public:void print(){cout << "this is Child" << endl;}
};int main()
{//Parent pp;//pp.print();Parent *p = new Child;p->print();return 0;
}
运行结果: