动态类型识别 : 利用多种方法进行动态类型识别




//动态类型识别 : 利用多态进行动态识别 
#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

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值