Cpp学习26 对象关系;继承
对象组合有两种基本子类型:组合和聚合。composition and aggregation
Composition 组合
要构成一个组合 ,一个物体和一个部分必须具有以下关系:
该部分(成员)是对象(类)的一部分。
一个部件(成员)一次只能属于一个对象(类)。
该部分(成员)的存在由对象(类)管理。
该部分(成员)并不知道对象(类)的存在。
Aggregation 聚合
要符合聚合的定义,一个整体对象及其各个部分必须具有以下关系:
该部分(成员)是对象(类)的一部分。
部件(成员)可以(如果需要)同时属于多个对象(类)。
该部分(成员)的存在 并非 由对象(类)管理。
该部分(成员)并不知道对象(类)的存在。
在聚合中,我们也把各个部分作为成员变量添加进去。然而,这些成员变量通常是引用或指针,指向在类作用域之外创建的对象。
std::reference_wrapper
它像引用一样工作,但也允许赋值和复制,因此它与 std::vector 等列表兼容。
好消息是,你其实不需要了解它的工作原理就能使用它。你只需要知道三件事:
std::reference_wrapper位于<functional>。- 当您创建
std::reference_wrapper包装的对象时,该对象不能是匿名对象(因为匿名对象具有表达式作用域,这将导致引用悬空)。 - 当你想从
std::reference_wrapper中取回你的对象时,可以使用get()成员函数。
Association 关联
任何能够将两个对象链接在一起的数据都足够了。
Dependencies 依赖
当一个对象调用另一个对象的功能来完成特定任务时,就会产生依赖关系 。
容器类
容器类是一种用于保存和组织另一种类型(可以是另一个类,也可以是基本类型)多个实例的类。(例如 std::array 或 std::vector)
值容器是组合 ,它存储所持有对象的副本(因此负责创建和销毁这些副本)。 引用容器是聚合 ,它存储指向其他对象的指针或引用(因此不负责创建或销毁这些对象)。
(然后教程写了个容器类IntArray出来)
std::initializer_list
当编译器遇到初始化列表时,它会自动将其转换为 std::initializer_list 类型的对象。因此,如果我们创建一个接受 std::initializer_list 参数的构造函数,就可以使用该初始化列表作为输入来创建对象。
std::initializer_list 位于 <initializer_list> 标头中。
总之是让自己写的容器类可以用列表初始化的方法。
继承
C++中的继承发生在类之间。在继承(is-a)关系中,被继承的类称为父类 、 基类或超类 ,而继承的类称为子类 、 派生类或子类 。
将 BaseballPlayer 类设为派生类
1 | class BaseballPlayer : public Person |
继承基类意味着我们无需在派生类中重新定义基类的信息。通过继承,我们会自动获得基类的成员函数和成员变量,然后只需添加所需的其他函数或成员变量即可。这不仅节省了工作量,还意味着如果我们更新或修改基类(例如添加新函数或修复错误),所有派生类都会自动继承这些更改!
派生类的构造顺序
C++ 分阶段构建派生类,从最基类(位于继承树顶部)开始,到最子类(位于继承树底部)结束。每个类构建完成后,都会调用该类的相应构造函数来初始化该类的相应部分。
派生类的构造函数和初始化
1 | class Derived: public Base |
公共成员可以被任何人访问。私有成员只能由同一类的成员函数访问。请注意,这意味着派生类不能直接访问基类的私有成员!派生类需要使用访问函数来访问基类的私有成员。
继承和访问说明符
受保护的访问说明符
protected 访问修饰符允许成员所属的类、友元类和派生类访问该成员。但是,受保护的成员不能从类外部访问。
优先考虑 private 成员 而非 protected 成员。
不同类型的继承及其对继承权的影响
基类中为 public 或 protected 的成员在派生类中可能会改变其访问修饰符。
除非有特殊原因,否则请使用公共继承。
public 继承时,成员权限:原public, protected都不变,原private无法访问。
protected 继承时,成员权限:原protected, protected都变为protected,原private无法访问。
private 继承时,成员权限:原protected, protected都变为private,原private无法访问。
向派生类添加新功能
正常写就是了。
调用继承的函数 和 重写行为
如果基类提供的行为足够,我们直接使用基类的行为。
要修改基类中定义的函数在派生类中的工作方式,只需在派生类中重新定义该函数即可。
基于原函数扩展:
1 | class Derived: public Base |
当我们尝试调用基类中的友元函数时,例如 operator<< 会遇到一个棘手的问题。因为基类的友元函数实际上并不属于基类本身,所以使用作用域解析限定符是行不通的。因此,我们需要一种方法,让 Derived 类暂时看起来像 Base 类,以便能够调用正确的函数版本。(使用 static_cast)
通过将 using 声明 using Base::print; 放在 Derived 中,Base::print(int) 会被优先于 Derived::print(double) 被选中。
1 | class Derived: public Base |
隐藏继承的功能
在派生类中,可以通过更改相关的访问说明符来隐藏基类中存在的功能,使其无法通过派生类访问。
1 | class Derived : public Base |
还可以将派生类中的成员函数标记为已删除,这样可以确保它们完全无法通过派生对象调用。
(函数:我一定得死吗?)
多重继承
C++ 提供了多重继承的功能。 多重继承允许派生类从多个父类继承成员。
混入类 (mixin,也拼作“mix-in”)是一个可以被其他类继承的小型类,用于向其他类添加属性。名称中的“mixin”表明该类旨在与其他类混合使用,而不是独立实例化。
除非其他选择会导致系统更加复杂,否则应避免多重继承。
- 标题: Cpp学习26 对象关系;继承
- 作者: 铁名_IronName
- 创建于 : 2026-08-14 16:03:44
- 更新于 : 2026-08-14 17:19:23
- 链接: https://blog.ironname.top/2026/Cpp/Cpp学习26/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。