127讲 继承
内容纲要

127讲 继承的语法、继承方式

继承的语法

file

#include <iostream> 
#include "string"

using namespace std;

class base_giegie {
    public:
    void ikun() {
        cout << "小黑子,又在黑人家giegie !!! " << endl;
    }

    void smallBlack() {
        cout << "食不食香精煎鱼?" << endl;
    }

    void protectMyGiegie() {
        cout << "人家哥哥下的蛋你有本事别吃!!!" << endl;
    }
};

class fengRenJi : public base_giegie {
public:
    void jianYu() {
        cout << "小黑子食不食香菜凤仁鸡?" << endl;
    }
};

class prison : public base_giegie {
public:
    void laoFan() {
        cout << "食不食香翅捞饭?" << endl;
    }
};

void main() {

    fengRenJi giegie;
    giegie.jianYu();
    giegie.ikun();
    giegie.smallBlack();
    giegie.protectMyGiegie();

    cout << "================================" << endl;

    prison jianyu;
    jianyu.laoFan();
    jianyu.ikun();
    jianyu.smallBlack();
    jianyu.protectMyGiegie();
}

继承方式

file

file

注意: 成员继承了父类的私有成员,隐藏了虽然不能直接访问,但是依旧会继承下去。

这么继承下来的作用是:如果父类有的函数需要访问父类的私有成员,那么继承下来就是为了让他康康!!!参考知乎文章如下

file

继承中的对象模型

补充一个知识点:

  1. 在类未声明成员的时候它占用的字节是 1,因为C++ 中每一个类中都要分配一个内存地址

    file

  2. 但是,如果类有一个成员或者多个成员,则占用空间按照实际的来。比如有一个int 类型的成员,则这个类它就占用4字节

  • 使用开发工具命令提示工具,查找类的继承对象模型
  1. 跳转盘符,
  2. cd 进入路径
  3. dir 查看当前文件信息,然后再输入下面的信息。

命令: E:\learnC++\继承与多态\继承与多态>cl /d1 reportSingleClassLayoutSheepTuo "多继承语法.cpp"

file

#include<iostream>
#include"string"
using namespace std;
class Base1 {
public:
    int m_A;
protected:
    int m_B;
private:
    int m_C;
};
class Son : public Base1 {
public:
    int m_D;
};
void test() {
    Son son;
    cout << "sizeof(son) = " << sizeof(Son) << endl;  //输出16,父类中所有的非静态成员属性都会继承下来,只是private 权限的成员被隐藏了。
}
void main() {
    test();
}

calculate:父类中私有成员也是被子类继承下去了,只是编译器给隐藏后访问不到

继承中构造和析构顺序

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

question:父类和子类的构造和析构的先后顺序是?

answer: 继承中,先调用父类构造函数,再调用子类构造。析构的时候先析构子类,然后再析构父类。

  • 我的理解是:

    • 1.因为父类东西要传给子类,所以得先有父类。

    2.子类先析构的原因是,如果父类先析构,那么子类的属性就会缺失,导致不可预见的错误,所以子类必须先析构,等子类属性消失后再析构父类。

继承中同名的成员处理方法

同名成员属性的访问方法。

file

同名成员函数的处理

file

file

#include <iostream> 
#include "string"
using namespace std;
class Base {
public:
    void func() {
        cout << "父类 的func() 被调用!" << endl;
    }
    void func(int a) {
        cout << "the \"func(int a)\"  of class Base has been used" << endl;
    }
};

class Son : public Base{
public:
    void func() {
        cout << "子类 的func() 被调用!!" << endl;
    }

};
void test() {
    Son mySon;
    mySon.Base::func();
    //mySon.func(100);  //哪怕是父类有重载,子类没重载,虽然子类父类能够区分,但是父类的成员函数依旧被隐藏掉了,只能加作用域:: 来访问父类的成员函数!!!!
}
void main() {
    test();
}

calculate:

  1. 子类对象可以直接访问到子类同名成员
  2. 子类对象加作用域可以访问到父类同名成员
  3. 当子类与父类拥有同名的成员函数,子类会隐藏父类中同名成员函数,加作用域可以访问到父类中同名函数。

继承下的同名静态成员的处理

回顾

  1. 静态成员类内声明,类外初始化。
  2. 在编译的时候就分配内存(不是分配计算机内存条物理意义上的内存,我猜是写进汇编语言,让程序运行的时候就给它分配内存)
  3. 静态成员函数只能访问静态成员。 我的理解: 因为它属于全局区,如果它有非静态成员,那么该成员的生命结束后销毁了,让静态函数怎么玩?。
  • 两种访问方式:1.通过对象访问。2.通过类名访问

file

解释:

Son::Base::m_A 第一个:: 表示通过类名方式访问 第二个:: 代表访问父类作用域下的成员

file

同理,静态成员函数如果子类出现同名,则父类的静态成员函数也会被隐藏

同名静态成员处理方式和非静态处理方式一样,只不过有两种访问方式(通过对象 和 通过类名)

多继承语法

在C++中不建议使用多继承。使用的时候容易冲突。因为项目往往不是一个人写的。 还是 JAVA 人性化

  • C++ 允许一个类继承多个类

语法: class 子类 : 继承方式 父类1 , 继承方式 父类2 ... 我的评价是,这是吕布行为。

//笑死了
class 丁原 {public: int m_A;};
class 董卓 {public: int m_A;};
class 王允 {public: int m_A;};
class 吕布 : public 丁原, public 董卓, public 王允 {
public:
    void toBeMultiSon(){
        cout << "爹!!!" << endl;
    }
    int m_A;
};

void main(){
    吕布 lvbu;
    //cout << lvbu.m_A; //这里会报错,因为吕布不知道要找哪一个爹,所以当父类中出现多个重名成员,需要加作用域::符号加以区分。
    cout << lvbu.董卓::m_A;
}

calculate:多继承中父类中如果出现了同名情况,子类使用时要加作用域。

菱形继承

菱形继承概念:

  1. 两个派生类继承同一个基类
  2. 又有某个类同时继承这两个派生类
  3. 这种继承称为菱形继承

file

file

利用虚继承可以解决菱形继承所遇到的问题!!!

virtual 关键字

file

calculate:

  • 菱形继承带来的主要问题是子类继承两份相同的数据,导致资源浪费以及毫无意义
  • 利用虚继承可以解决菱形继承的问题。
#include <iostream>
#include "string"
using namespace std;

class  Animal {
public:
    int m_Age;
};

class Sheep : virtual public Animal {};  //继承时使用关键字,virtual

class Tuo : virtual public Animal {};

class SheepTuo : public Sheep, public Tuo {};

void test() {
    SheepTuo st;
    st.Tuo::m_Age = 100;
    st.Sheep::m_Age = 200;

    cout << st.Tuo::m_Age << endl;
    cout << st.Sheep::m_Age << endl;
}

void main() {
    test();
}

虚基类继承继承的不是数据,而是指针。vbptr ( virtual base pointer ) 虚基类指针

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇