C++多态复习(看这一篇就够了,然后多码代码,多验证)

一.

#include <iostream>

using namespace std;
const double PI = 3.14;

class Shape
{
public:
    Shape();
    ~Shape();
    double calcArea();
};

class Circle:public Shape{
public:
    Circle(double r);
    ~Circle();
    double calcArea();
protected:
    double m_dR;
};

class Rect:public Shape{
public:
    Rect(double width,double height);
    ~Rect();
    double calcArea();
protected:
    double m_dWidth;
    double m_dHeight;
};
Shape::Shape()
{
    cout<<"Shape()"<<endl;
}

Shape::~Shape()
{
    cout<<"~Shape()"<<endl;
}

double Shape::calcArea()
{
    cout<<"Shape-->calcArea()"<<endl;
    return 0;
}

Circle::Circle(double r)
{
    cout<<"Circle()"<<endl;
    m_dR = r;
}

Circle::~Circle(){
    cout<<"~Circle()"<<endl;
}

double Circle::calcArea()
{
    cout<<"Circle-->calcArea()"<<endl;
    return PI*m_dR*m_dR;
}

Rect::Rect(double width,double height){
    cout<<"Rect()"<<endl;
    m_dHeight = height;
    m_dWidth = width;
}

Rect::~Rect(){
    cout<<"~Rect()"<<endl;
}

double Rect::calcArea()
{
    cout<<"Rect-->clacArea()"<<endl;
    return m_dHeight*m_dWidth;
}

int main()
{
    Shape *shape1 = new Rect(3,6);
    Shape *shape2 = new Circle(5);

    shape1->calcArea();
    shape2->calcArea();

    delete shape1;
    shape1 = NULL;
    delete shape2;
    shape2 = NULL;
    return 0;
}

运行结果:
在这里插入图片描述
在父类的方法前加上virtual关键字后:

#include <iostream>

using namespace std;
const double PI = 3.14;

class Shape
{
public:
    Shape();
    ~Shape();
    virtual double calcArea();
};

class Circle:public Shape{
public:
    Circle(double r);
    ~Circle();
    double calcArea();
protected:
    double m_dR;
};

class Rect:public Shape{
public:
    Rect(double width,double height);
    ~Rect();
    double calcArea();
protected:
    double m_dWidth;
    double m_dHeight;
};
Shape::Shape()
{
    cout<<"Shape()"<<endl;
}

Shape::~Shape()
{
    cout<<"~Shape()"<<endl;
}

double Shape::calcArea()
{
    cout<<"Shape-->calcArea()"<<endl;
    return 0;
}

Circle::Circle(double r)
{
    cout<<"Circle()"<<endl;
    m_dR = r;
}

Circle::~Circle(){
    cout<<"~Circle()"<<endl;
}

double Circle::calcArea()
{
    cout<<"Circle-->calcArea()"<<endl;
    return PI*m_dR*m_dR;
}

Rect::Rect(double width,double height){
    cout<<"Rect()"<<endl;
    m_dHeight = height;
    m_dWidth = width;
}

Rect::~Rect(){
    cout<<"~Rect()"<<endl;
}

double Rect::calcArea()
{
    cout<<"Rect-->clacArea()"<<endl;
    return m_dHeight*m_dWidth;
}

int main()
{
    Shape *shape1 = new Rect(3,6);
    Shape *shape2 = new Circle(5);

    shape1->calcArea();
    shape2->calcArea();

    delete shape1;
    shape1 = NULL;
    delete shape2;
    shape2 = NULL;
    return 0;
}

运行结果:
在这里插入图片描述
多态的语法核心是virtual关键字,必须使用virtual才能使多个类间建立多态关系。

二.

虚析构函数:防止内存泄漏

#include <iostream>

using namespace std;
const double PI = 3.14;

class Shape
{
public:
    Shape();
    virtual double calcArea();
    virtual ~Shape();
};
class Coordinate
{
public:
    Coordinate(int x, int y);
    ~Coordinate();
private:
    int m_iX;
    int m_iY;
};
Coordinate::Coordinate(int x, int y)
{
    cout<<"Coordinate"<<endl;
    m_iX = x;
    m_iY = y;
}
Coordinate::~Coordinate()
{
    cout<<"~Coordinate"<<endl;
}

class Rect:public Shape{
public:
    Rect(double width,double height);
    ~Rect();
    double calcArea();
protected:
    double m_dWidth;
    double m_dHeight;
};

class Circle:public Shape
{
public:
    Circle(int x, int y, double r);
    ~Circle();
    virtual double calcArea();
private:
    double m_dR;
    Coordinate *m_pCenter;
};

Shape::Shape()
{
    cout<<"Shape()"<<endl;
}

Shape::~Shape()
{
    cout<<"~Shape()"<<endl;
}

double Shape::calcArea()
{
    cout<<"Shape-->calcArea()"<<endl;
    return 0;
}

Circle::Circle(int x, int y, double r)
{
    cout<<"Circle()"<<endl;
    m_dR = r;
    m_pCenter = new Coordinate(x,y);
}

Circle::~Circle(){
    cout<<"~Circle()"<<endl;
    delete m_pCenter;
    m_pCenter = NULL;
}

double Circle::calcArea()
{
    cout<<"Circle-->calcArea()"<<endl;
    return PI*m_dR*m_dR;
}

Rect::Rect(double width,double height){
    cout<<"Rect()"<<endl;
    m_dHeight = height;
    m_dWidth = width;
}

Rect::~Rect(){
    cout<<"~Rect()"<<endl;
}

double Rect::calcArea()
{
    cout<<"Rect-->clacArea()"<<endl;
    return m_dHeight*m_dWidth;
}
int main()
{
    Shape *shape1 = new Rect(3,6);
    Shape *shape2 = new Circle(3,4,5.0);

    shape1->calcArea();
    shape2->calcArea();

    delete shape1;
    shape1 = NULL;
    delete shape2;
    shape2 = NULL;
    return 0;
}

运行结果:
在这里插入图片描述

关于virtual的限制:

普通函数不能是虚函数,virtual只能修饰某个类的成员函数。
静态成员函数不能是虚函数,因为static函数是与类同生共死的,不依赖于对象。
内联函数不能是虚函数,如果修饰inline函数,计算机会忽略inline而把它变成虚函数。
构造函数不能为虚函数。

纯虚函数:

virtual double calaPerimeter() = 0;

含有纯虚函数的类叫作抽象类。
抽象类无法实例化对象。

接口类

仅含有纯虚函数的类称为接口类。
只有成员函数,而且成员函数都是纯虚函数。

RTTI:运行时类型识别

cout<<typeid(*obj).name()<<endl;
    if(typeid(*obj)==typeid(Bird)){
        Bird *Bird = dynamic_cast<Bird *>(obj);
    }

dynamic_cast只能应用于指针和引用的转换
要转换的类型中必须包含虚函数
转换成功返回子类的地址,失败返回NULL。

typeid返回一个type_info对象的引用。只能获取对象的实际类型,而不能是指针的。
如果想通过基类的指针获得派生类的数据类型,基类必须带有虚函数。

异常处理

try…catch…尝试正常逻辑,捕获异常
throw… 抛出异常,让catch捕获处理

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值