c++ 语法多态

多态分为两类

静态多态:函数重载和运算符重载属于静态多态复用函数名

动态多态: 派生类和虚函数实现运行时多态。

静态多态和动态多态区别

静态多态的函数地址早绑定:编译阶段确定函数地址

动态多态函数地址晚绑定:运行阶段确定函数位置

class AnimalBase{
public:
    int m_age;
    // 虚函数 函数在运行阶段绑定
    virtual void speek() {
        cout << "AnimalBase speek" <<  endl;
    }
    
};

class Dog : public AnimalBase
{
    void speek() override {
        cout << "dog speek" <<  endl;
    }
};

class Pag : public AnimalBase {
    void speek() override {
        cout << "Pag speek" <<  endl;
    }
};
//
void doWork(AnimalBase &animal) {
    animal.speek();
}

void test58() {
    Pag p;
    doWork(p);
    Dog d;
    doWork(d);
}
int main(int argc, const char * argv[]) {
    // insert code here...
    std::cout << "Hello, World!\n";
    test58();
    std::cout << "end!\n";
    return 0;
}

动态多态满足条件

1.有继承关系

2.重写父类中的虚函数 (返回值 函数名 参数列表 完全一致)

动态多态使用

父类的指针或者引用 指向子类对象。

 

多态原理

当类中有虚函数的时候 类里面会有一个虚函数表指针。指向虚函数表

vfptr v virtual f function ptr 指针

当子类继承于父类的时

 没有重写虚函数

子类会从父类继承虚函数表c++ 语法多态_第1张图片

当重写后

子类虚函数表内部会替换成子类虚函数表地址

当父类的指针或者引用指向子类的时候就发生了多态

c++ 语法多态_第2张图片c++ 语法多态_第3张图片

上边是父类的 内部结构图

下边是没有重写时类的内部结构图 c++ 语法多态_第4张图片

重写后类的内部结构图 c++ 语法多态_第5张图片

 多态案例

多态的好处

1.组织结构清晰

2.可读性强

#include 
#include 
using namespace std;
class AbstureCalculator {
public:
    int m_num1;
    int m_num2;
    virtual int getResult() {
        return 0;
    };
};

class SumCalculator : public AbstureCalculator {
    int getResult() override {
        return m_num1 + m_num2;
    }
};

class MinusCalculator : public AbstureCalculator {
    int getResult() override {
        return m_num1 - m_num2;
    }
};
class MulCalculator : public AbstureCalculator {
    int getResult() override {
        return m_num1 * m_num2;
    }
};

void test60() {
    AbstureCalculator *calculator = new SumCalculator;
    calculator->m_num1 = 100;
    calculator->m_num2 = 2000;
    cout << calculator->getResult() << endl;
    delete calculator;
    calculator = new MinusCalculator;
    calculator->m_num1 = 2000;
    calculator->m_num2 = 100;
    cout << calculator->getResult() << endl;
    delete calculator;

    calculator = new MulCalculator;
    calculator->m_num1 = 2000;
    calculator->m_num2 = 100;
    cout << calculator->getResult() << endl;
    delete calculator;

}


// 普通写法
class Calculator {
    
public:
    int m_num1;
    int m_num2;
    int getResult(string oper) {
        if (oper == "+") {
            return m_num1 + m_num2;
        } else if (oper == "-") {
            return m_num1 - m_num2;
        } else if (oper == "*") {
            return m_num1 * m_num2;
        } else if (oper == "/") {
            return m_num1 / m_num2;
        }
        return  0;
    };
};
void test53() {
    Calculator  c;
    c.m_num1 = 100;
    c.m_num2 = 200;
    c.getResult("*");
}

int main(int argc, const char * argv[]) {
    // insert code here...
    std::cout << "Hello, World!\n";
    test53();
    test60();
    std::cout << "end!\n";
    return 0;
}

纯虚函数和抽象类

在多态中,通常父类中虚函数的实现是毫无意义的主要都是调用子类重写的内容

因此可以将虚函数改成纯虚函数。

纯虚函数的语法

virtual返回值类型 函数名(参数列表)=0;

当类中有了纯虚函数 这个类称为抽象类。

抽象类特点

无法实例化对象。

子类必须重写抽象类中的纯虚函数,否则也属于抽象类


#include 
#include 
using namespace std;
class Super {
public:
    //纯虚函数
    //只要有一个纯虚函数 这个类称为抽象类
    //抽象类特点
    //1.无法实例化对象
    //2.抽象类必须重写纯虚函数否则也是抽象类
    virtual void func() = 0;
};
class Son : public Super {
public:
    void func() override {
        cout << "virtual" << endl;
    }
};

void test61() {
    //Super s;//Variable type 'Super' is an abstract class
    Son s;
    s.func();
}
int main(int argc, const char * argv[]) {
    // insert code here...
    std::cout << "Hello, World!\n";
    test61();
    std::cout << "end!\n";
    return 0;
}
#include 
#include 
using namespace std;
class AbstractDrink{
public:
    virtual void boil() = 0;
    virtual void brew() = 0;
    virtual void cup() = 0;
    virtual void putSome() = 0;
    void makeDrink() {
          boil();
          brew();
          cup();

    }
    virtual ~AbstractDrink(){

    }
};
class coffe : public AbstractDrink {
public:
    void boil() override  {
        cout << "煮水" << endl;
    }
    void brew() override {
        cout << "加入coffe" << endl;

    }
    void cup() override {
        cout << "放入杯子" << endl;
    }
    void putSome() override {
        cout << "加入辅料 " << endl;
    }
};
class Tea : public AbstractDrink {
public:
    void boil() override  {
        cout << "煮水" << endl;
    }
    void brew() override {
        cout << "加入茶叶" << endl;

    }
    void cup() override {
        cout << "放入杯子" << endl;
    }
    void putSome() override {
        cout << "加入柠檬 " << endl;
    }
};

void doMakeDrink(AbstractDrink *drink) {
    drink->makeDrink();
}
void test62() {
    AbstractDrink *drink = new coffe;
    doMakeDrink(drink);
    delete drink;
    drink = new Tea;
    doMakeDrink(drink);
    delete drink;
//    Delete called on 'AbstractDrink' that is abstract but has non-virtual destructor
}
int main(int argc, const char * argv[]) {
    // insert code here...
    std::cout << "Hello, World!\n";
    test62();
    std::cout << "end!\n";
    return 0;
}

虚析构和纯虚析构

解决父类指针指向子类的时候 释放不干净的问题

若子类中没有堆区数据 可以不写虚析构或纯虚析构

拥有纯虚析构函数的类也属于抽象类

#include 
using namespace std;
class AbstractA {
public:
    int *m_a;
    virtual void info() = 0;
    AbstractA(){
        cout << "AbstractA init" << endl;
    }
//    // 虚析构
//    virtual~AbstractA(){//Delete called on 'AbstractA' that is abstract but has non-virtual destructor
//        cout << "~AbstractA()" << endl;
//    }
    //纯虚析构 必须要实现
    virtual ~AbstractA() = 0;
};
AbstractA::~AbstractA(){
    cout << "AbstractA::~AbstractA()" << endl;
}

class ClassB: public AbstractA {
public:
    void info() override {
        cout << *m_a << endl;
    }
    ClassB(int a) {
        m_a = new int(a);
        cout << "ClassB init" << endl;
    }
    ~ClassB(){
        if (m_a != nullptr) {
            delete m_a;
        }
        cout << " ~ClassB()" << endl;
    }
};
void test63() {
    AbstractA *a = new ClassB(12);
    a->info();
    delete a;
}
int main(int argc, const char * argv[]) {
    // insert code here...
    std::cout << "Hello, World!\n";
    test63();
    std::cout << "end!\n";
    return 0;
}

c++ 语法多态_第6张图片


#include 
#include "mathutil.hpp"
#include 
#include "People.hpp"
#include "Phone.hpp"
using namespace std;
class  Cpu{
public:
    virtual void calculate() = 0;
    virtual ~Cpu(){
        cout << "~Cpu" << endl;
    }
};
class  VideoCard{
public:
    virtual void display() = 0;
    virtual ~VideoCard(){
        cout << "~VideoCard" << endl;

    }

};
class  Memory{
public:
    virtual void storege() = 0;
    virtual ~Memory(){
        cout << "~Memory" << endl;
    }

};
class Computer{
private:
    Cpu *m_cpu;
    VideoCard *m_videoCard;
    Memory *m_memory;
public:
    Computer(Cpu *cpu,VideoCard *card,Memory *m) {
        m_cpu = cpu;
        m_videoCard = card;
        m_memory = m;
    };
    ~Computer(){
        if(m_cpu != nullptr) {
            delete m_cpu;
        }
        
        if(m_videoCard != nullptr) {
            delete m_videoCard;
        }
        if(m_memory != nullptr) {
            delete m_memory;
        }

    }
    void work() {
        m_cpu -> calculate();
        m_videoCard -> display();
        m_memory -> storege();
    }
};
class InterCpu: public Cpu {
public:
    void calculate() override {
        cout << "inter cpu 开始工作了" << endl;
    }
    virtual ~InterCpu(){
        cout << "~InterCpu" << endl;
    }

};
class InterVideoCard : public VideoCard {
public:
    void display() override {
        cout << "inter 显卡 开始工作了" << endl;
    }
    virtual ~InterVideoCard(){
        cout << "~InterVideoCard" << endl;
    }

};
class InterMemort : public Memory {
    void storege() override {
        cout << "inter 内存条 开始工作了" << endl;
    }
    virtual ~InterMemort(){
        cout << "~InterMemort" << endl;
    }

};


class DellCpu: public Cpu {
public:
    void calculate() override {
        cout << "Dell cpu 开始工作了" << endl;
    }
    virtual ~DellCpu(){
        cout << "~DellCpu" << endl;
    }

};
class DellVideoCard : public VideoCard {
public:
    void display() override {
        cout << "Dell 显卡 开始工作了" << endl;
    }
    virtual ~DellVideoCard(){
        cout << "~DellVideoCard" << endl;
    }

};
class DellMemory : public Memory {
    void storege() override {
        cout << "Dell 内存条 开始工作了" << endl;
    }
    virtual ~DellMemory(){
        cout << "~DellMemory" << endl;
    }

};

void test64() {
    Cpu *c = new InterCpu;
    VideoCard *v = new InterVideoCard;
    Memory *m = new InterMemort;
    
    Computer *cvm = new  Computer(c,v,m);
    cvm->work();
    delete cvm;
    
    
   c = new DellCpu;
   v = new DellVideoCard;
   m = new DellMemory;
   cvm = new  Computer(c,v,m);
   cvm->work();
   delete cvm;
}

int main(int argc, const char * argv[]) {
    // insert code here...
    std::cout << "Hello, World!\n";
    test64();
    std::cout << "end!\n";
    return 0;
}

你可能感兴趣的:(c++,开发语言)