【C++学习】对象特性--继承

一、继承的方式

基础语句

cpp 复制代码
//类A继承类B,B为基类(父类),A为派生类(子类)
//class A:pulic B{};
#include <iostream> //标准输入输出控件
#include <iomanip>
#include <string>  //使用string声明字符串时必须包含
#include <cstdlib> //汉化
using namespace std;
/*继承基本语句*/

class BaseClass
{
public:
    void baseClassCout() { cout << "父类" << endl; };
};

class SonClass1 : public BaseClass
{
public:
    void sonClassCout() { cout << "子类1" << endl; };
};

void test1()
{
    SonClass1 son1;
    son1.baseClassCout();
    son1.sonClassCout();
};

int main()
{
    system("chcp 65001 >nul"); // 汉化
    // using std::cout;
    test1();

    return 0;
}

继承方式

复制代码
公共继承 public
保护继承 protected
私有继承 private

各继承方式的特点

使用public继承时,父类的public成员在子类中依旧为public成员,父类的protected成员在子类中为protected成员,按照此规律,继承特点如下表所示

注意:父类的 private成员 三种继承的子类都不能访问

复制代码
公共继承 public     父 public->子 public      父 protected->子 protected
保护继承 protected  父 public->子 protected   父 protected->子 protected
私有继承 private    父 public->子 private     父 protected->子 private

二、父子实例的构造函数与析构函数执行顺序

复制代码
父类构造函数->子类构造函数->子类析构函数->父类析构函数
cpp 复制代码
class Parent {
public:
    Parent() { cout << "Parent 构造函数" << endl; }
    ~Parent() { cout << "Parent 析构函数" << endl; }  // 非虚析构(仅演示顺序)
};

class Child : public Parent {
public:
    Child() { cout << "Child 构造函数" << endl; }
    ~Child() { cout << "Child 析构函数" << endl; }
};

int main() {
    Child c;  // 创建子类对象,出作用域时自动销毁
    return 0;
}

三、父子实例同名成员访问方式

访问同名变量

cpp 复制代码
#include <iostream>
using namespace std;

class Parent {
public:
    int num = 10;  // 父类成员变量
};

class Child : public Parent {
public:
    int num = 20;  // 子类同名成员变量(隐藏父类的num)
};

int main() {
    Child c;
    cout << c.num << endl;          // 直接访问:子类的num → 输出 20
    cout << c.Parent::num << endl;  // 显式指定父类作用域:父类的num → 输出 10

    Child* ptr = &c;
    cout << ptr->num << endl;       // 指针访问子类num → 20
    cout << ptr->Parent::num << endl; // 指针访问父类num → 10
    return 0;
}

访问同名函数

若父子类存在同名非虚函数(参数列表可不同),子类函数会隐藏父类所有同名函数(无论参数是否相同),直接调用时默认执行子类函数

cpp 复制代码
class Parent {
public:
    void func() { cout << "Parent::func()" << endl; }
    void func(int x) { cout << "Parent::func(int) " << x << endl; }  // 重载函数
};

class Child : public Parent {
public:
    void func() { cout << "Child::func()" << endl; }  // 隐藏父类所有func()
};

int main() {
    Child c;
    c.func();          // 调用子类func() → 输出 Child::func()
    // c.func(10);     // 编译报错!子类隐藏了父类的func(int),无法直接调用
    
    // 调用父类的func()和func(int)
    c.Parent::func();       // 输出 Parent::func()
    c.Parent::func(10);     // 输出 Parent::func(int) 10
    return 0;
}

四、多继承语法

cpp 复制代码
#include <iostream>
using namespace std;

// 父类1:表示"能跑"的特性
class Runable {
public:
    void run() {
        cout << "可以奔跑" << endl;
    }
};

// 父类2:表示"能飞"的特性
class Flyable {
public:
    void fly() {
        cout << "可以飞翔" << endl;
    }
};

// 子类:同时继承 Runable 和 Flyable(如"飞毯"既可以跑也可以飞)
class Carpet : public Runable, public Flyable {
public:
    void display() {
        cout << "这是一个神奇的飞毯:" << endl;
    }
};

int main() {
    Carpet c;
    c.display();  // 子类自身方法
    c.run();      // 继承自 Runable 的方法
    c.fly();      // 继承自 Flyable 的方法
    return 0;
}

五、菱形继承(钻石继承)

当多继承中出现 "两个父类继承自同一个基类" 的情况,会导致子类中存在间接基类的多份副本,引发数据冗余和访问歧义

问题演示

cpp 复制代码
// 顶层基类
class Object {
public:
    int id;
};

// 中间父类 A 和 B,都继承 Object
class A : public Object {};
class B : public Object {};

// 子类 C 同时继承 A 和 B,导致 C 中包含两份 Object::id
class C : public A, public B {};

int main() {
    C c;
    // c.id = 10;  // 编译报错:歧义(A::id 还是 B::id?)
    c.A::id = 10;  // 需显式指定,繁琐且不合理
    c.B::id = 20;
    return 0;
}

虚继承解决

通过在中间父类的继承方式前加 virtual 关键字,确保顶层基类在子类中只存在一份副本,避免冗余和歧义

cpp 复制代码
class Object {
public:
    int id;
};

// 中间父类用虚继承
class A : virtual public Object {};  // 虚继承 Object
class B : virtual public Object {};  // 虚继承 Object

// 子类 C 继承 A 和 B,Object 仅一份副本
class C : public A, public B {};

int main() {
    C c;
    c.id = 10;  // 无歧义,直接访问唯一的 id
    return 0;
}
相关推荐
西贝爱学习7 小时前
【QT】安装包
开发语言·qt
徐凤年lll8 小时前
python 初学2
开发语言·python
2301_801252228 小时前
Mybatis的添加和修改功能
java·开发语言·mybatis
艾莉丝努力练剑8 小时前
【Git:基本操作】深度解析Git:从初始Git到熟悉基本操作
大数据·linux·c++·人工智能·git·gitee·指令
AI_56788 小时前
AI换脸技术安全指南:3条法律红线与合规实践
人工智能·学习·it
行思理9 小时前
IntelliJIdea 创建java spring boot程序
java·开发语言·spring boot
散峰而望9 小时前
C语言刷题(一)
c语言·开发语言·编辑器·github·visual studio
CN-Dust9 小时前
【C++】2025CSP-J第二轮真题及解析
开发语言·c++·算法
温柔一只鬼.9 小时前
Java数组
java·开发语言·算法