#C++ Day29 November 13 2025

//Object – Oriented 8 – 1 Inheritance grammar

//继承的语法

#include <iostream>

using namespace std;

//你可以把继承理解成 数据结构中的一颗树   

/*

动物

  / \

  猫     狗

*/

/*

继承的语法

class 子类 : 继承方式 父类{}

子类 -> 派生类

父类 -> 基类

写了两个类 发现他们有一些共性 把共性抽出来实现一个新的类 那两个类成为新类的派生类 这样能省掉一些冗余代码

*/

class Animal {

public:

void eat() {

cout << “吃” << endl;

}

};

class Cat : public Animal {

//类 类名: public 继承的类

public:

/*void eat() {

cout << “吃” << endl;

}*/

void sayHi() {

cout << “喵喵~” << endl;

}

};

class Dog : public Animal {

public:

/*void eat() {

cout << “吃” << endl;

}*///放动物类

void sayHi() {

cout << “汪汪汪~” << endl;

}

};

int main() {

Cat c;

Dog d;

c.eat();

d.eat();

c.sayHi();

d.sayHi();

return 0;

}

//Object – Oriented 8 – 2 Inheritance Mode

//继承方式

#include <iostream>

using namespace std;

/*

* 继承方式

公共 public

保护 protected

私有 private

继承方式有三种 访问权限也有三种 组合一下 就是 3*3=9种

class 子类名 : 继承方式 父类名{};

上面代表父类访问权限

下面代表子类继承方式

| public | protected | private |

| public | public | protected | 无法访问 |

| protected | protected | protected | 无法访问 |

| private | private | private | 无法访问 |

public:类内可以访问,类外也可以访问

protected:类内可以访问,类外也可以访问,且子类可以访问

private:类内可以访问,类外不可访问,且子类不可访问

*/

class Animal {

public:

int m_pub;

protected:

int m_pro;

private:

int m_pri;

};

class Cat : public Animal {

public:

Cat() {

m_pub = 1;

m_pro = 2;

//m_pri = 3;//父类私有成员,子类公有继承,无法访问

}

};

class BossCat : public Cat {

public:

BossCat() {

m_pub = 1;

m_pro = 2;//爷爷类的保护成员   父类的保护成员,子类还是保护成员 再继承一次发现类内可以访问 所以不是 是保护保护

//m_pri = 3;//父类私有成员,子类公有继承,无法访问

}

};

void testCar() {

Cat c;

c.m_pub = 1;

//c.m_pro = 2;//不行,保护成员在类外部不可以访问,在类内部才可以访问,类内可以访问,类外不可以访问,要么是私有,要么是保护

}

class Dog : protected Animal {

public:

Dog() {

m_pub = 1;

m_pro = 2;

//m_pri = 3;//父类私有成员,子类保护继承,无法访问

}

};

//现在证明两个变量都是保护的

class PoliceDog :public Dog {

public:

PoliceDog() {

m_pub = 1;//证明不是私有 因为私有变量无论怎么继承 子类都拿不到 这个变量在父类Dog中一定不是私有成员,

m_pro = 2;//证明不是私有 因为私有变量无论怎么继承 子类都拿不到 这个变量在父类Dog中一定不是私有成员 

//所以这两个变量在父类里面一定是保护成员

}

};

void testDog() {

Dog d;

//d.m_pub = 1;  //类无法访问的话,要么是保护,要么是私有,我们还无法验证是保护还是私有

//d.m_pro = 2;//类无法访问的话,要么是保护,要么是私有,我们还无法验证是保护还是私有

}

class Pig : private Animal {

public:

Pig() {

m_pub = 1;

m_pro = 2;

//m_pri = 3;//父类私有成员,子类私有继承,无法访问

}

};

class WildPig :public Pig {

public:

WildPig() {

m_pub = 1;//证明该变量在父类 Pig中是私有的 因为如果是保护 子类公有继承一定能访问到

m_pro = 2;//证明该变量在父类 Pig中是私有的 因为如果是保护 子类公有继承一定能访问到

}

};

void testPig() {

Pig p;

//p.m_pub = 1;//类无法访问的话,要么是保护,要么是私有

//p.m_pro = 2;//类无法访问的话,要么是保护,要么是私有

}

int main() {

return 0;

}

//Ov Construction and Destruction Order

//构造和析构顺序 

#include <iostream>

using namespace std;

/*

继承中,构造链里,先构造的后析构

d->c->b->a  (d继承了c继承了b继承了a)

构造顺序:a b c d

析构顺序:d c b a

*/

class Animal {

public:

Animal() {

cout << “Animal 构造” << endl;

}

~Animal() {

cout << “Animal 析构” << endl;

}

};

class Cat : public Animal{

public:

Cat() {

cout << “Cat 构造” << endl;

}

~Cat() {

cout << “Cat 析构” << endl;

}

};

class BossCat : public Cat {

public:

BossCat() {

cout << “BossCat 构造” << endl;

}

~BossCat() {

cout << “BossCat 析构” << endl;

}

};

void Test() {

//Animal a;//调用函数时生成a对象 生成对象时调用构造函数 然后当函数销毁时 调用析构函数

//Cat c;//先调用父类的构造函数,再调自己构造函数,再调自己的析构函数,最后调用父类的析构函数,有点像一个个括号

BossCat b;//先调用父类的构造函数,再调自己构造函数,再调自己的析构函数,最后调用父类的析构函数,有点像栈 后进先出

}

int main() {

Test();//调用函数时生成a对象 生成对象时调用构造函数 然后当函数销毁时 调用析构函数

return 0;

}

//Object – Oriented 8 – 4 Access to Same – Named Attributes

//同名属性访问

#include <iostream>

using namespace std;

//同名属性:父类和子类都有一个名字相同的属性

// 子类不会覆盖父类,因为存储的位置不在一个内存地址上

//

class Animal {//父类

public:

Animal() {

m_Data = 17981;

}

int m_Data;

};

class Cat:public Animal {//子类

public:

Cat() {

m_Data = 29812;

}

int m_Data;

};

void Test() {

Cat c;

cout << c.m_Data << endl; 

cout << c.Animal::m_Data << endl;//这个数据还在,用一个作用域来进行访问就好了

cout << &(c.m_Data) << endl;//不是同一个地址

cout << &(c.Animal::m_Data) << endl;//不是同一个地址

}

int main() {

Test(); //子类看起来会覆盖父类同名属性,其实并没有被覆盖掉

return 0;

}

//Object – Oriented 8 – 5 Access to Same – Named Function

//同名函数访问

#include <iostream>

using namespace std;

//父类和子类有一个名称相同的函数

class Animal{

public:

Animal() {

}

void eat() {

cout << “动物吃东西” << endl;

}

};

class Cat : public Animal {

public:

Cat() {

}

void eat() {

Animal::eat();//用作用域 这样就可以先调 动物吃东西

cout << “猫吃东西” << endl;

}

};

int main() {

Cat c;

c.eat(); //输出猫吃东西, 

//c.Animal::eat();//就像同名变量一样 直接点出来就是能拿到自己的 这样就能拿到父类的函数了

return 0;

}

//Object – Oriented 8 – 6 Multiple Inheritance

//多继承

#include <iostream>

using namespace std;

//多继承:子类有一个,它可以继承多个父类

class BaseA {

public:

int m_A;

int m_Base;

BaseA() :m_A(0),m_Base(520){}//构造函数

};

class BaseB {

public:

int m_B;

int m_Base;

BaseB() :m_B(0), m_Base(1314) {}//构造函数

};

class BaseC {

public:

int m_C;

BaseC() :m_C(0) {}//构造函数

};

class Son : public BaseA, public BaseB, public BaseC {

};

int main() {

Son s;

s.m_A = 1;

s.m_B = 2;

s.m_C = 3;

//s.m_Base = 8;//这样写会导致不明确,因为父类A和B有一个同名变量

s.BaseA::m_Base = 8; //用定义域来拿到不同的m_Base值

s.BaseB::m_Base = 9;

cout << &s.BaseA::m_Base << endl;//不是同一个地址

//如果存储在同一个地址 那么编译器就会识别到

cout << &s.BaseB::m_Base << endl;//不是同一个地址

cout << sizeof(s) << endl; //总共继承了来自三个父类的5个整型 一个整型 4字节

return 0;

}