【C++】day08 - 【类型识别】【dynamic_cast】【typeid】【虚析构函数】

一、类型识别

2.1dynamic_cast<类型>(对象);

在多态的代码中,父类指针只能调用父类中的相关数据。子类扩展的部分无法调
	用,有时要恢复父类指针指向的具体对象的类型。而这个恢复就要用动态
	类型转换。
动态类型转换必须满足多态性(必须要有虚函数)
如果转换成功返回非空指针,转换失败则返回NULL指针
程序举例:

```cpp
#include <iostream>
using namespace std;
class Animal{
    
    
	public:
	virtual void run(){
    
    
		cout << "动物的跑" << endl;
	}
	void show(){
    
    
		cout << "animal show()" << endl;
	}
};
class Dog:public Animal{
    
    
	public:
	void run(){
    
    
		cout << "狗狂奔" << endl;
	}
	void dogfun(){
    
    
		cout << "狗看家" << endl;
	}
};
class Fish:public Animal{
    
    
	string name;
	public:
	void run(){
    
    
		cout << "鱼在水里游" << endl;
	}
	void fishfun(){
    
    
		cout << name << endl;
		cout << "鱼被观赏" << endl;
	}
};
void showAnimal(Animal *a){
    
    
	a->run();
	/*是狗就完成dogfun,是鱼则就完成fishfun()*/
	if(dynamic_cast<Fish*>(a)){
    
    
		((Fish*)a)->fishfun();
	}
	else if(dynamic_cast<Dog*>(a)){
    
    
		((Dog*)a)->dogfun();
	}
}
int main(){
    
    
	Animal *pa = new Dog();
	
}

1.2 typeid

	typeid可返回类型的信息,返回的类型为typeinfo
	class typeinfo{
		...
		name(){}			返回类型的名字
		operator==()函数	判断两个typeinfo是否相等
		operator!=()函数	判断两个typeinfo是否不等
		...
	};
	 程序举例:
using namespace std;
class Animal{
    
    
	/*父类中必须有虚函数,否则会把父类指针指向的对象识别成父类型*/
	public:
	virtual void show(){
    
    
	} 
};
class Dog:public Animal{
    
    
	
};
class Cat:public Animal{
    
    
	
}; 
int main(){
    
    
	cout << typeid(int).name() << endl;//i
	cout << typeid(int*).name() << endl;//pi
	cout << typeid(Animal).name() << endl;//6Animal
	Animal *pa = new Dog();
	cout << typeid(pa).name() << endl;//P6Animal
	cout << typeid(*pa).name() << endl;//3Dog
	Animal *pc = new Cat();
	if(typeid(Dog)==typeid(*pc)){
    
    
		cout << "pc指向了Dog" << endl;
	}
	if(typeid(Cat)==typeid(*pc)){
    
    
		cout << "pc指向了Cat" << endl;
	}
	int * pa1 = new int[10];//一维
	int (*parr)[3][4] = new int[5][3][4];//三维数组。parr是二维数组指针
	cout << typeid(parr).name() << endl;/*PA3_A4_i,即指针指向三行四
											列int型的*/
	cout << typeid(*parr).name() << endl;/*每个元素的类型为A3_A4_i*/
}

二、虚析构函数

2.1概念

	在析构函数上加一个virtual
	注:只有成员函数和析构函数可以加virtual

2.2作用

	当父类型的指针或者引用 指向子类对象时,释放这个指针对应的堆内存,
		则只有父类的析构函数被调用,子类的析构函数不进行调用,即子类
		的堆内存并没有释放,这就造成了内存泄漏。
	用到虚构函数的情况:
		当父类中有虚函数时,应该把父类的析构函数定义成虚析构函数。
		子类和父类中都有自己的堆内存分配时,应该把父类的析构函数定义成虚
			析构函数。
	程序举例:
#include <iostream>
#include <typeinfo>
using namespace std;
class Animal{
    
    
	public:
	Animal(){
    
    
		cout << "Animal()" << endl;
	}
	virtual ~Animal(){
    
    
		cout << "~Animal()" << endl;
	}
};
class Dog:public Animal{
    
    
	public:
	Dog(){
    
    
		cout << "Dog()" << endl; 
	}
	~Dog(){
    
    
		cout << "~Dog()" << endl;
	}
};

int main(){
    
    
	Animal *pa = new Dog();
	delete pa;/*调用了父类和子类的析构函数。你要是不在父类的析构函数前
				加virtual,则子类的析构函数就没办法调用*/
}

猜你喜欢

转载自blog.csdn.net/weixin_45519751/article/details/108435676
今日推荐