6.类和对象_继承

//继承是面向对象三大特性之一
//语法:class 子类 : 继承方式 父类
//子类也叫派生类,父类也叫基类
//继承方式有三种:公共继承、保护继承、私有继承
//公共继承:原来public和protected关系不变
//保护继承:public和protected全变成protected
//私有继承:public和protected全变成private
//
//继承中的对象模型
//父类中所有非静态的成员属性,都会被子类继承
//父类中私有的成员属性被编译器隐藏,因此访问不到,但是确实被继承
//(利用开发人员命令提示工具查看对象模型)cl /d1 reportSingleClassLayout类名 文件名
//继承中构造和析构的顺序
//先构造父类后构造子类
//先析构子类再析构父类
//继承同名成员处理方式
//访问子类同名成员 直接访问
//访问父类同名成员 加作用域
//如果子类出现和父类同名成员函数,会隐藏掉父类中所用同名成员函数(包括重载),同理需要加作用域访问
//同名静态成员处理方式相同
//
//多继承语法
//class 子类 : 继承方式 父类1, 继承方式 父类2, ...
//同名成员访问方式相同
//实际开发不建议使用
//
//菱形继承
//两个派生类继承同一个基类,又有某个类同时继承两个派生类
//菱形继承导致这个基类的数据到后面这个类的数据有两份,其实只需要一份,资源浪费
//利用虚继承解决菱形继承问题

#include <iostream>
#include <string>
using namespace std;

class BasePage
{
public:
    void header()
    {
        cout << "PUBLIC HEADER" << endl;
    }
    void footer()
    {
        cout << "PUBLIC FOOTER" << endl;
    }
};

class Java : public BasePage
{
public:
    void content()
    {
        cout << "JAVE CONTENT" << endl;
    }
};

void test01()
{
    Java ja;
    ja.header();
    ja.footer();
    ja.content();
}

//同名成员处理

class Base
{
public:
    int m_A;
    Base() :m_A(100) {}
};

class Son : public Base
{
public:
    int m_A;
    Son() : m_A(200) {}
};

void test02()
{
    Son s;
    cout << "s.m_A = " << s.m_A << endl;
    cout << "s.Base::m_A=" << s.Base::m_A << endl;
}

//菱形继承
class AllBase
{
public:
    int m_A;
};

//继承方式前加入virtual变为虚继承,AllBase称为虚基类
class Son1 :virtual public AllBase {};
class Son2 :virtual public AllBase {};
class Grandson :public Son1, public Son2 {}; //只需要一份m_A

/*
class Grandson  size(12):
        +---
 0      | +--- (base class Son1)
 0      | | {vbptr}
        | +---
 4      | +--- (base class Son2)
 4      | | {vbptr}
        | +---
        +---
        +--- (virtual base AllBase)
 8      | m_A
        +---
*/
//vbptr 虚基类指针
//v - virtual b - base ptr - pointer
//指向vbtable(虚基类表)
/*
Grandson::$vbtable@Son1@:
 0      | 0
 1      | 8 (Grandsond(Son1+0)AllBase)

Grandson::$vbtable@Son2@:
 0      | 0
 1      | 4 (Grandsond(Son2+0)AllBase)
vbi:       class  offset o.vbptr  o.vbte fVtorDisp
         AllBase       8       0       4 0
*/
//表格中记录的是地址的偏移量
//即vbptr+偏移量=&m_A
void test03()
{
    Grandson gs;
    gs.Son1::m_A = 18;
    gs.Son2::m_A = 28;
    cout << "gs.Son1::m_A=" << gs.Son1::m_A << endl;
    cout << "gs.Son2::m_A=" << gs.Son2::m_A << endl;
    cout << "gs.m_A=" << gs.m_A << endl;
}

int main()
{
    //test02();
    test03();
    system("pause");
    return 0;
}