//动态类型识别 : 利用多态进行动态识别
#include <iostream>
using namespace std;
class Parent
{
public:
enum{ ID = 0 };
virtual int type()
{
return ID;
}
};
class Child : public Parent
{
public:
enum{ ID = 1 };
int type()
{
return ID;
}
int add(int a,int b)
{
return a+b;
}
};
void test(Parent* p)
{
if(p->type() == Child::ID)
{
Child* c = (Child*)p;
cout << "dynamic type is " << "Child" << endl;
cout << c->add(2,3) << endl;
}
if(p->type() == Parent::ID)
{
cout << "dynamic type is " << "Parent" << endl;
}
}
int main()
{
Parent parent;
Child child;
test(&parent);
test(&child);
return 0;
}
dynamic type is Parent
dynamic type is Child
5
由于使用唯一的ID,使得程序的维护性大大降低,故进行改进,使用字符串来动态识别
#include <iostream>
#include <string.h>
using namespace std;
class Parent
{
public:
//enum{ ID = 0 };
virtual const char* type()
{
//return ID;
return "Parent";
}
};
class Child : public Parent
{
public:
//enum{ ID = 1 };
const char* type()
{
//return ID;
return "Child";
}
int add(int a,int b)
{
return a+b;
}
};
void test(Parent* p)
{
//if(p->type() == Child::ID)
if(strcmp(p->type(),"Child"))
{
Child* c = (Child*)p;
cout << "dynamic type is " << "Child" << endl;
cout << c->add(2,3) << endl;
}
//if(p->type() == Parent::ID)
if(strcmp(p->type(),"Parent"))
{
cout << "dynamic type is " << "Parent" << endl;
}
}
int main()
{
Parent parent;
Child child;
test(&parent);
test(&child);
return 0;
}
缺点是,使用字符串比较函数,strcmp可维护性提高了,但是效率却降低了
改进:dynamic_cast<>
#include <iostream>
using namespace std;
class Parent
{
public:
virtual ~Parent() //
{
}
};
class Child : public Parent
{
public:
int add(int a,int b)
{
return a+b;
}
};
void test(Parent* p)
{
Child* c = dynamic_cast<Child*>(p); /<span style="font-family: Arial, Helvetica, sans-serif;">/转换成功,c不为空,转换失败,c为空指针</span>
if(c != NULL)
{
cout << "dynamic type is " << "Child" << endl;
cout << c->add(2,3) << endl;
}
else if(c == NULL)
{
cout << "dynamic type is " << "Parent" << endl;
}
}
int main(int argc,char* argv[])
{
Parent parent;
Child child;
test(&parent);
test(&child);
return 0;
}
dynamic type is Parent
dynamic type is Child
5
缺点,,只能用于具有虚函数的类族
改进:使用typeid
// typeid 的使用
#include <iostream>
#include <typeinfo>
using namespace std;
class Parent
{
public:
virtual ~Parent()
{
}
};
class Child : public Parent
{
public:
int add(int a,int b)
{
return a+b;
}
};
void test(Parent* p)
{
/*
Child* c = dynamic_cast<Child*>(p); /<span style="font-family: Arial, Helvetica, sans-serif;">/转换成功,c不为空,转换失败,c为空指针</span>
if(c != NULL)
{
cout << "dynamic type is " << "Child" << endl;
cout << c->add(2,3) << endl;
}
else if(c == NULL)
{
cout << "dynamic type is " << "Parent" << endl;
}
*/
if(typeid(*p) == typeid(Child))
{
Child* c = dynamic_cast<Child*>(p); //转换成功,c不为空,转换失败,c为空指针
cout << "dynamic type is " << "Child" << endl;
cout << c->add(2,3) << endl;
}
if(typeid(*p) == typeid(Parent))
{
cout << "dynamic type is " << "Parent" << endl;
}
}
int main(int argc,char* argv[])
{
Parent parent;
Child child;
int index;
char ch;
const type_info& tip = typeid(parent);
const type_info& tic = typeid(child);
const type_info& tii = typeid(index);
const type_info& tich = typeid(ch);
//*.name()输出的字符串依赖于编译器,不同的编译器输出不同的字符串,因此可移植性差
cout << tip.name() << endl;
cout << tic.name() << endl;
cout << tii.name() << endl;
cout << tich.name() << endl; //
//最佳的解决方案¸
cout << (typeid(parent) == typeid(Parent)) << endl;
cout << (typeid(child) == typeid(Child)) << endl;
cout << (typeid(index)== typeid(int)) << endl;
cout << (typeid(ch) == typeid(char)) << endl;
test(&parent);
test(&child);
return 0;
}
6Parent
5Child
i
c
1
1
1
1
dynamic type is Parent
dynamic type is Child
5