C++单继承,多重继承,虚拟继承与内存布局

本文深入探讨C++的继承机制,包括单继承、多重继承及其可能导致的歧义问题,特别是菱形继承(钻石型继承)的挑战。文章详细介绍了虚继承的概念,解释了虚继承如何解决重复继承问题,同时讨论了虚继承对内存布局的影响,以及在不同架构下的表现。此外,还提到了接口类在C++中的应用和内存布局的细节,强调了在使用多继承时应谨慎考虑设计和性能因素。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Multiple Inheritance - C++

  1. 多继承比单继承更复杂,引入了歧义的问题,以及虚继承的必要性;
  2. 虚继承在大小,速度,初始化,复制的复杂性上有不小的代价,当虚基类中没有数据时还是比较合适的;
  3. 多继承有时也是有用的。典型的场景是:public继承自一些接口类,private继承自哪些实现相关的类。

歧义

class A{
   
public:
    void func();
};
class B{
   
private:
    bool func() const;
};
class C: public A, public B{
    ... };

C c;
c.func();           // 歧义!

解决冲突的时候就必须

c.A::func();

多继承菱形

在这里插入图片描述

class File{
   };
class InputFile: public File{
   };
class OutputFile: public File{
   };
class IOFile: public InputFile, public OutputFile{
   };

这样的层级在C++标准库中也存在,例如basic_ios, basic_istream, basic_ostream, basic_iostream。

IOFile的两个父类都继承自File,那么File的属性(比如filename)应该在IOFile中保存一份还是两份呢? 这是取决于应用场景的,就File::filename来讲显然我们希望它只保存一份,但在其他情形下可能需要保存两份数据。 C++还是一贯的采取了自己的风格:都支持!默认是保存两份数据的方式。如果你希望只存储一份,可以用virtual继承:

class File{
   };
class InputFile: virtual public File{
   };
class OutputFile: virtual public File{
   };
class IOFile: public InputFile, public OutputFile{
   };

代价:

  1. 虚继承类的对象会更大一些;
  2. 虚继承类的成员访问会更慢一些;
  3. 虚继承类的初始化更反直觉一些。继承层级的最底层(most derived class)负责虚基类的初始化,而且负责整个继承链上所有虚基类的初始化。

对于这些复杂性,建议

  1. 如果能不使用多继承,就不用他;
  2. 如果一定要多继承,尽量不在里面放数据,也就避免了虚基类初始化的问题。

接口类

这样一个不包含数据的虚基类和Java或者C#提供的interface有很多共同之处,这样的类在C++中称为接口类,一个Person的接口类是这样的:

class IPerson {
   
public:
    virtual ~IPerson();
    virtual std::string name() const = 0;
    virtual std::string birthDate() const = 0;
};

内存布局

普通多重继承内存布局

class Base
{
   
public:
 
    Base(
实验题目1:班级学生学期成绩管理系统 (1)程序功能简介 灵活运用类的继承、对象成员等机制,设计一个能够实现班级学生学期成绩管理的程序。 (2)程序设计说明 ① 个人信息类CPerson的数据成员有姓名、性别、年龄、身份证号等数据成员,成员函数根据需要自行设计; ② 学生类CStudent从CPerson派生,并增加学号、CCourse对象成员数组(大小至少3个)等数据成员,并根据需要自行设计成员函数,包括能够求解所选修课程的总学分、显示某个学生基本信息和课程信息的成员函数; ③ 课程类CCourse包括课程名、学分、分数、任课老师等数据成员,成员函数根据需要自行设计; ④ 班级类CClass的数据成员有班级名称、班级人数、CStudent对象成员数组(大小由构造函数确定)等。本班级类CClass的对象成员数组需要在构造函数中用new动态分配内存空间,在析构函数中用delete释放。在CClass类中设计包括能够求解最高成绩、最低成绩和平均成绩以及通过学号查找并输出某个学生全部信息(例如Seek())等功能在内的成员函数; ⑤ 构造三十个学生的数据,每个学生都有三门课程成绩,输出并显示这些数据; ⑥ 根据类的需要添加适当的其它成员,编写完整的程序并测试。 (3)程序调试运行 运行程序查看结果,并进行源代码调试和优化。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值