zoukankan      html  css  js  c++  java
  • dynamic_cast和typeid

    1. C++有三个支持RTTI的元素。

    • 如果可能的话,dynamic_cast运算符将使用一个指向基类的指针来生成一个指向派生类的指针,否则,该运算符返回0——空指针。
    • typeid运算符返回一个对type_info对象的引用。
    • type_info结构存储了有关特定类型的信息。

    只能将RTTI用于包含虚函数的类层次结构,原因在于只有对于这种类层次结构,才应该将派生对象的地址赋给基类指针。

    2. 通常,如果指向的对象(*pt)的类型为Type或者是从Type直接或间接派生而来的类型,则下面的表达式将指针pt转换为Type类型的指针:

    dynamic_cast<Type *> (pt)

    否则,结果为0,即空指针。

    3. typeid运算符使得能够确定两个对象是否为同种类型。它与sizeof有些相像,可以接受两种参数:

    • 类名
    • 结果为对象的表达式

    typeid运算符返回一个对type_info对象的引用,其中,type_info是在头文件typeinfo中定义的一个类。type_info类重载了==和!=运算符,以便可以使用这些运算符来对类型进行比较。如果pg指向的是一个Magnificent对象,则下述表达式的结果为true,否则为false:

       typeid(Magnificent) == typeid(*pg)

    如果pg是一个空指针,程序将引发bad_typeid异常。该异常类型是从exception类派生而来的,是在头文件typeinfo中声明的。

       type_info类的实现随厂商而异,但包含一个name()成员,该函数返回一个随实现而异的字符串,通常是类的名称。例如,下面的语句显示指针pg指向的对象所属的类定义的字符串:

    cout << “Now processing type ” << typeid(*pg).name() << “. ”;

    #include <iostream>
    #include <cstdlib>
    #include <ctime>
    #include <typeinfo>
    
    using namespace std;
    
    class Grand
    {
    private:
    	int hold;
    public:
    	Grand(int h = 0) : hold(h){}
    	virtual void Speak() const { cout << "I am a grand class!
    "; }
    	virtual int Value() const { return hold; }
    };
    
    class Superb : public Grand
    {
    public:
    	Superb(int h = 0) :Grand(h){}
    	void Speak() const{ cout << "I am a Superb class!!
    "; }//const可以删除
    	virtual void Say() const
    	{
    		cout << "I hold the superb value of " << Value() << endl;
    	}
    };
    
    class Magnificent : public Superb
    {
    private:
    	char ch;
    public:
    	Magnificent(int h = 0, char cv = 'A') : Superb(h), ch(cv){}
    	void Speak() const
    	{
    		cout << "I am a magnificent class!!!
    ";
    	}
    	void Say() const
    	{
    		cout << "I hold the character " << ch << " and the integer " << Value() << "!" <<endl;
    	}
    };
    
    Grand * Getone();
    
    int main()
    {
    	srand(time(0));
    	Grand *pg;
    	Superb *ps;
    	for (int i = 0; i < 5; i++)
    	{
    		pg = Getone();
    		cout << "Now processing type " << typeid(*pg).name() << ".
    ";
    		pg->Speak();
    		if (ps = dynamic_cast<Superb *>(pg))
    			ps->Say();
    		if (typeid(Magnificent) == typeid(*pg))
    			cout << "You are really Magnificent.
    ";
    	}
    	return 0;
    }
    
    Grand * Getone()
    {
    	Grand *p;
    	switch (rand() % 3)
    	{
    	case 0:
    		p = new Grand(rand() % 100);
    		break;
    	case 1:
    		p = new Superb(rand() % 100);
    		break;
    	case 2:
    		p = new Magnificent(rand() % 100, 'A' + rand() % 26);
    		break;
    	default:
    		break;
    	}
    
    	return p;
    }
    

      运行得到结果如下:

  • 相关阅读:
    【纯水题】POJ 1852 Ants
    【树形DP】BZOJ 1131 Sta
    【不知道怎么分类】HDU
    【树形DP】CF 1293E Xenon's Attack on the Gangs
    【贪心算法】CF Emergency Evacuation
    【思维】UVA 11300 Spreading the Wealth
    【树形DP】NOI2003 逃学的小孩
    【树形DP】BZOJ 3829 Farmcraft
    【树形DP】JSOI BZOJ4472 salesman
    【迷宫问题】CodeForces 1292A A NEKO's Maze Game
  • 原文地址:https://www.cnblogs.com/lakeone/p/4938710.html
Copyright © 2011-2022 走看看