多态:
产生多态的基础是继承关系,没有继承就没有多态
多态的语法核心是virtual关键字,必须适用virtual才能在多个类之间简历多态关系
可以通过该指针调用子类的方法
RTTI --运行时类型识别
typeid(*obj).name() -- 识别出该指针指向具体的类(通过基类的指针获取派生类的数据类型)
Bird *bird = dynamic_cast<Bind *>(obj); -- Bind 指具体的子类 ,这个方法适用于通过基类获取到具体的子类,转换为具体的子类
dynamic_cast注意事项:
只能应用于指针和引用之间的转换
要转换类型中必须包含虚函数
转换成功返回子类的地址,失败返回NULL
typeid注意事项:
typeid返回一个type_info对象的引用
如果想通过基类的指针获取派生类的数据类型,基类必须带有虚函数
产生多态的基础是继承关系,没有继承就没有多态
多态的语法核心是virtual关键字,必须适用virtual才能在多个类之间简历多态关系
可以通过该指针调用子类的方法
virtual->虚函数(virtual修饰的函数)
列子:
#ifndef SHAPE_H
#define SHAPE_H// SHAPE_H
class Shape
{
public:
Shape();
virtual ~Shape();
public:
virtual double calcArea();
};
#endif
#ifndef RECT_H
#define RECT_H
#pragma once
#include "Shape.h";
class Rect:public Shape
{
public:
Rect(int width,int height);
virtual ~Rect();
public:
int m_dWidth;
int m_dHeight;
virtual double calcArea();
};
#endif // !RECT_H
#ifndef CIRCLE_H
#define CIRCLE_H
//上面的是避免重复包含
#pragma once
#include "Shape.h"
class Circle:public Shape
{
public:
Circle(int r);
virtual ~Circle();
public:
int m_dR;
virtual double calcArea();
};
#endif // !CIRCLE_H
/*多态:
产生多态的基础是继承关系,没有继承就没有多态
多态的语法核心是virtual关键字,必须适用virtual才能在多个类之间简历多态关系
可以通过该指针调用子类的方法
virtual->虚函数(virtual修饰的函数)*/
/*多态中存在的问题--内存泄漏
解决方案 -- 虚析构函数 virtual修饰析构函数
virtual使用限制:
1、普通函数不能是虚函数(virtual int text(){} ×的)
2、静态成员函数不能是虚函数(virtual static int getCount(){} ×的)
3、内联函数不能是虚函数(inline virtual int eat(){} ×的)
4、构造函数不能是虚函数(virtual Animal(){} ×的)*/
/*仅含纯虚函数的类称为接口类
接口类可以被继承,不能实例化
不能含有数据成员
一个类中所有成员函数都是由 virtual修饰并赋值为0(纯虚函数) 列:virtual void setData() = 0; 该类就为接口类
*/
Shape *p1 = new Shape();
Shape *p2 = new Circle(10);
Shape *p3 = new Rect(3,5);
p1->calcArea();
p2->calcArea();
p3->calcArea();
delete p1;
p1 = NULL;
delete p2;
p2 = NULL;
delete p3;
p3 = NULL;
//虚函数和虚析构函数的实现
//函数指针
//函数的覆盖和隐藏
//含有纯虚函数的类不可以实例化
RTTI --运行时类型识别
typeid(*obj).name() -- 识别出该指针指向具体的类(通过基类的指针获取派生类的数据类型)
Bird *bird = dynamic_cast<Bind *>(obj); -- Bind 指具体的子类 ,这个方法适用于通过基类获取到具体的子类,转换为具体的子类
dynamic_cast注意事项:
只能应用于指针和引用之间的转换
要转换类型中必须包含虚函数
转换成功返回子类的地址,失败返回NULL
typeid注意事项:
typeid返回一个type_info对象的引用
如果想通过基类的指针获取派生类的数据类型,基类必须带有虚函数
只能够获取对象的实际类型
继承关系不是RTTI的充分条件,只是必要条件,所以存在继承关系的类不一定可以用RTTI技术
#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;
/**
* 定义移动类:Movable
* 纯虚函数:move
*/
class Movable
{
public:
virtual void move() = 0;
};
/**
* 定义公交车类:Bus
* 公有继承移动类
* 特有方法carry
*/
class Bus : public Movable
{
public:
virtual void move()
{
cout << "Bus -- move" << endl;
}
void carry()
{
cout << "Bus -- carry" << endl;
}
};
/**
* 定义坦克类:Tank
* 公有继承移动类
* 特有方法fire
*/
class Tank :public Movable
{
public:
virtual void move()
{
cout << "Tank -- move" << endl;
}
void fire()
{
cout << "Tank -- fire" << endl;
}
};
/**
* 定义函数doSomething含参数
* 使用dynamic_cast转换类型
*/
void doSomething(Movable *obj)
{
obj->move();
if(typeid(*obj) == typeid(Bus))
{
Bus *bus = dynamic_cast<Bus *>(obj);
bus->carry();
}
if(typeid(*obj) == typeid(Tank))
{
Tank *tank = dynamic_cast<Tank *>(obj);
tank->fire();
}
}
int main(void)
{
Bus b;
Tank t;
doSomething(&b);
doSomething(&t);
return 0;
}
异常:
c++异常 try{}catch(){}捕获异常,throw抛出异常
捕获异常,catch要具体捕获是就要对应绝具体的类型,也可以直接就用Exception来捕获,这种是属于模糊(全部)的。