Day10-C++基础之继承和多态

继承

#include<iostream>
using namespace std;
​
//继承语法: class 子类:继承方式 父类
//如果是public继承:公共和保护权限同父类,私有不可访问。 protected继承:父类的公共权限和保护权限再子类中均是保护权限,私有不可访问
//private访问:父类中公共和保护权限均变为私有,父类私有不可访问
//普通页面
class BasePage{
public:
    void header(){
        cout<<"首页、公开课..."<<endl;
    }
    void footer(){
        cout<<"帮助中心、交流合作"<<endl;
    }
    void left(){
        cout<<"Java、C++、Python"<<endl;
    }
};
​
//Java页面
class Java:public BasePage{
public:
    void content(){
        cout<<"Java学科视频"<<endl;
    }
};
//Python页面
class Python:public BasePage{
public:
    void content(){
        cout<<"Python学科视频"<<endl;
    }
};
​
//继承中同名处理方式
class Base{
public:
    Base(){
        m_A=100;
    }
    void func(){
        cout<<"Base func调用"<<endl;
    }
    int m_A;
    static int m_B;
};
int Base::m_B=100;
class Son:public Base{
public:
    Son(){
        m_A=200;
    }
    void func(){
        cout<<"Son func调用"<<endl;
    }
    int m_A;
    static int m_B;
};
int Son::m_B=200;
​
//多继承
class Base1{
public:
    Base1(){
        m_A=100;
    }
    int m_A;
};
​
class Base2{
public:
    Base2(){
        m_A=200;
    }
    int m_A;
};
//多继承语法
class newSon:public Base1,public Base2{
public:
    newSon(){
        m_C=300;
        m_D=400;
    }
    int m_C;
    int m_D;
};
​
//菱形继承
//动物类
class Animal{
public:
    int m_Age;
};
//羊类
class Sheep:virtual public Animal{ //在继承前加关键字变虚继承,因为年龄数据只有一份即可,这里有两个,所以用虚继承讲将其变成一个
​
};
//驼类
class Camel:virtual public Animal{
​
};
//羊驼类
class SheepCamel:public Sheep,public Camel{
​
};
​
int main(){
    Java java;
    java.content();
    Python python;
    python.content();
​
    Son s;
    cout<<s.m_A<<endl;//200
    //通过子类对象访问父类的同名成员,需要加作用域
    cout<<s.Base::m_A<<endl;//100
    s.func();//子类成员
    s.Base::func();//通过子类调用父类成员函数
    //注意:只要子类出现同名函数,就会隐藏掉所有父类的同名函数,包括重载,需要加作用域
​
    //同名静态成员
    cout<<s.m_B<<endl;//200
    cout<<s.Base::m_B<<endl;//100
    //或者通过类名访问
    cout<<Son::m_B<<endl;
    cout<<Son::Base::m_B<<endl;
    //静态成员方法同理
​
    //多继承
    newSon new_son;
    cout<<new_son.Base1::m_A<<endl;//两个父类间出现相同成员名,要标明作用域
    cout<<new_son.Base2::m_A<<endl;
​
    SheepCamel sc;
    sc.Sheep::m_Age=20;
    sc.Camel::m_Age=30;
    //当菱形继承的时候,两个父类有相同的数据,加作用域进行区分
    cout<<sc.m_Age<<endl;//30
    cout<<sc.Sheep::m_Age<<endl;//30
​
    return 0;
}

多态

#include<iostream>
#include<string>
using namespace std;
​
//多态
class Animal{
public:
    //变成虚函数
    virtual void speak(){
        cout<<"说话"<<endl;
    }
};
​
class Cat:public Animal{
public:
    void speak(){
        cout<<"喵"<<endl;
    }
};
​
//执行说话函数
//地址早绑定,在编译阶段就确定了函数地址
void doSpeak(Animal &animal){//想执行猫的函数需要变成虚函数
    animal.speak();
}
​
//总结:多态首先得有继承关系,其次子类要重写父类的虚函数
​
//案例:计算器
class AbstractCalc{
public:
    virtual int getResult(){
        return 0;
    }
    int m_Num1;
    int m_Num2;
};
​
//加法
class AddCalc:public AbstractCalc{
public:
    int getResult(){
        return m_Num1+m_Num2;
    }
};
​
//减法
class SubCalc:public AbstractCalc{
public:
    int getResult(){
        return m_Num1-m_Num2;
    }
};
​
//乘法
class MulCalc:public AbstractCalc{
public:
    int getResult(){
        return m_Num1*m_Num2;
    }
};
​
//除法
class DivCalc:public AbstractCalc{
public:
    int getResult(){
        return m_Num1/m_Num2;
    }
};
​
//纯虚函数
class Base{
public:
    virtual void fun()=0;//在虚函数的基础上=0,因为发现以前虚函数体用不上
    //有纯虚函数的类叫抽象类,无法实例化.且抽象类的子类要重写纯虚函数,不然也是抽象类
};
​
class Son:public Base{
public:
    virtual void fun(){
        cout<<"纯虚函数重写"<<endl;
    }
};
​
//虚析构
class Big{
public:
    Big(){
        cout<<"Big构造函数"<<endl;
    }
    virtual ~Big(){//虚析构:解决了释放问题
        cout<<"Big析构函数"<<endl;
    }
    virtual void speak()=0;
};
​
class Small:public Big{
public:
    Small(string name){
        cout<<"Small构造函数"<<endl;
        m_Name=new string(name);
    }
    ~Small(){
        if(m_Name!=NULL){
            cout<<"Small析构函数"<<endl;
            delete m_Name;
            m_Name=NULL;
        }
    }
    virtual void speak(){
        cout<<*m_Name<<"说话"<<endl;
    }
    string *m_Name;
};
​
int main(){
    Cat cat;
    doSpeak(cat);
​
    //计算器测试
    //多态实现:父类指针或引用指向子类对象
    AbstractCalc *abc=new AddCalc;
    abc->m_Num1=10;
    abc->m_Num2=10;
    cout<<abc->getResult()<<endl;
    delete abc;
​
    //纯虚函数
    Base *base=new Son;
    base->fun();
    
    //注意到一个问题,多态时父类指针不会调用子类中析构函数,导致子类如果有堆区数据会泄露
    //所以引入虚析构
    Big *big=new Small("Tom");
    big->speak();
    delete big;//在释放堆区空间时不会执行子类的析构函数
    //虚析构解决
​
    return 0;
}
  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值