C++核心编程-类和对象-继承

继承

继承是面向对象三大特性之一  减少重复代码

语法  class 子类:继承方式 父类

子类也称为派生类;父类也称为基类

#include <iostream>
#include <ostream>
#include <string>
using namespace std;
//继承实现
//公共页面类
class BasePage{
public:
    void header(){
        cout<<"公共头部"<<endl;
    }
    void footer(){
        cout<<"公共底部"<<endl;
    }
    void left(){
        cout<<"公共分类列表"<<endl;
    }
};

//Java 页面
class Java: public BasePage{
public:
    void content(){
        cout<<"Java"<<endl;
    }
};
//C++页面
class CPP: public BasePage{
public:
    void content(){
        cout<<"CPP"<<endl;
    }
};
void test01(){
    Java java;
    CPP cpp;
    java.footer();
    java.content();
    cpp.footer();
    cpp.content();
}
int main(){
    test01();
}

继承方式:

公共继承;保护继承;私有继承

  

继承中的对象模型

父类中所有非静态成员属性都会被子类继承下去

父类中私有成员属性被编译器隐藏,无法访问,但确实被继承。


继承中构造和析构顺序

子类继承父类后,当创建子类对象,也会调用父类的构造函数

继承中构造和析构顺序如下:先构造父类,再构造子类;先析构子类,再析构父类。

继承同名成员处理方式

当子类与父类出现同名的成员,如何通过子类对象,访问到子类或父类中同名的数据?

访问子类同名成员,直接访问即可;

访问父类同名成员,需要加作用域。

 

#include <iostream>
#include <ostream>
#include <string>
using namespace std;
class Base{
public:
    Base(){
        m_A=100;
    }
    void func(){
        cout<<"Base"<<endl;
    }
    void func(int a){
        cout<<"Base int a"<<endl;
    }
    int m_A;
};
class Son: public Base{
public:
    Son(){
        m_A=200;
    }
     void func(){
        cout<<"Son"<<endl;
    }
    int m_A;
};
void test01(){
    Son s;
    cout<<s.m_A<<endl;
    cout<<s.Base::m_A<<endl;//同名成员属性
}
void test02(){
    Son s1;
    s1.func();
    s1.Base::func();//同名成员函数
    //如果子类中出现和父类同名的成员函数,子类的同名成员会隐藏掉父类中所有同名成员函数,
如果想访问到父类中被隐藏的同名成员函数,需要加作用域
    s1.func(100);
    s1.Base::func(100);
}
int main(){
    test02();
}

继承中同名静态成员处理方式

静态成员和非静态成员出现同名,处理方式一致

#include <iostream>
#include <ostream>
#include <string>
using namespace std;
class Base{
public:
    static int m_A;
    static void func(){
        cout<<"Base"<<endl;
    }
};
int Base::m_A=100;//静态成员变量,类内声明,类外初始化
class Son: public Base{
public:
    static int m_A;
    static void func(){
        cout<<"Son"<<endl;
    }
};
int Son::m_A=200;
void test01(){
    //同名静态成员属性
    Son s;
    //1.通过对象访问
    cout<<s.m_A<<endl;
    cout<<s.Base::m_A<<endl;
    //2.通过类名访问
    cout<<Son::m_A<<endl;
    //第一个::代表通过类名的方式访问
    //第二个::代表父类作用域下
    cout<<Son::Base::m_A<<endl;
}
void test02(){
    Son s1;
    s1.func();
    s1.Base::func();
    //通过类名
    Son::func();
    Son::Base::func();
}
int main(){
    test01();
    test02();
}

多继承语法

语法:class 子类 : 继承方式 父类1  ,继承方式 父类2  。。。

多继承可能会引发父类中有成员出现,需要加作用域区分

菱形继承(钻石继承)

两个子类继承同一个父类

又有某个类同时继承两个子类

 

菱形继承的问题:

羊继承了动物的数据,驼同样继承了动物的数据,当草泥马使用数据时,就会产生二义性;

草泥马继承自动物的数据继承了两份,其实这份数据只需要一份即可。

 vbptr   virtual base pointer  虚基类指针 指向 virtual base table

#include <iostream>
#include <ostream>
#include <string>
using namespace std;
class Animal{
public:
    int m_Age;
};
//利用虚继承 解决菱形继承的问题
//继承前加上关键字 virtual变为虚继承,Aniaml类称为虚基类
class Sheep:virtual public Animal{

};
class Tuo:virtual public Animal{

};
class SheepTuo:public Sheep,public Tuo{

};
void test01(){
    SheepTuo st;
    //当菱形继承,两个父类拥有相同数据,需要加作用域区分
    st.Sheep::m_Age=18;
    st.Tuo::m_Age=28;
    //这份数据只需要一份,菱形继承导致数据有两份,浪费资源
    cout<<st.m_Age<<endl;
}
int main(){
    test01();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值