c++ 基础 -- 多态

多态:
产生多态的基础是继承关系,没有继承就没有多态
多态的语法核心是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来捕获,这种是属于模糊(全部)的。



猜你喜欢

转载自blog.csdn.net/u014231961/article/details/79695707