Effective C++ 条款39:明智而审慎地使用 private 继承

devtools/2025/1/3 4:29:17/

文章目录

    • 条款39:明智而审慎地使用 private 继承
      • 示例 1:private 继承无隐式转换
      • 示例 2:private 继承 vs 复合
      • 示例 3:empty base 最优化 (EBO)
      • 适用场景
      • 总结

条款39:明智而审慎地使用 private 继承

private 继承 是一种特殊的继承方式,其主要特点包括:

  1. 无隐式转换:如果类之间的继承关系是 private,编译器不会自动将 derived class 的对象转换为 base class 的对象。
  2. 成员访问权限变化:由 private base class 继承而来的所有成员,在 derived class 中都会变为 private 属性,即使它们在 base class 中是 public 或 protected 的。

复合 (composition) 不同,private 继承还支持特定的优化,如 empty base 最优化 (Empty Base Optimization, EBO)。这是实现轻量级对象的重要技术,尤其在一些性能敏感的程序库开发中。


示例 1:private 继承无隐式转换

class Base {
public:void display() const {std::cout << "Base display" << std::endl;}
};class Derived : private Base {
public:void show() const {display(); // Derived 可以访问 Base 的成员}
};int main() {Derived d;d.show();// d.display(); // 错误:Base 的成员在 Derived 中是 private 的return 0;
}

在这个例子中,DerivedBase 继承了 display,但客户代码不能直接访问它,因为 private 继承使得 Base 的成员变为 Derived 的私有成员


示例 2:private 继承 vs 复合

复合版本

class Base {
public:void display() const {std::cout << "Base display" << std::endl;}
};class Derived {
public:void show() const {base.display(); // 使用复合的 Base 对象}private:Base base; // 复合关系
};

private 继承版本

class Base {
public:void display() const {std::cout << "Base display" << std::endl;}
};class Derived : private Base {
public:void show() const {display(); // 直接访问 Base 的成员}
};

两者的主要区别在于,复合关系 更适合描述 “has-a” 关系,而 private 继承 更适合描述 “is-implemented-in-terms-of” 关系。


示例 3:empty base 最优化 (EBO)

当基类为空时,private 继承可以避免不必要的内存开销。以下示例展示了 EBO 的效果:

class EmptyBase {};class Derived : private EmptyBase {
public:int value;
};int main() {std::cout << "Size of EmptyBase: " << sizeof(EmptyBase) << std::endl;std::cout << "Size of Derived: " << sizeof(Derived) << std::endl;return 0;
}

在此例中,Derived 类继承自 EmptyBase,但其大小可能与 int 相同。这是因为编译器可以利用 EBO 消除空基类的内存占用。


适用场景

  • 复合优先:如果你只是需要实现某种功能,复合通常是更直观的选择。
  • private 继承:当你需要从基类中继承实现(而非接口),或者需要利用 EBO 最优化内存布局时,可以使用 private 继承。

总结

  • private 继承 适用于描述 “is-implemented-in-terms-of” 关系。
  • 与复合相比,private 继承可以直接访问基类成员,但不能隐式转换为基类类型。
  • 在需要优化对象尺寸时,private 继承可能优于复合,因为它可以触发 EBO

http://www.ppmy.cn/devtools/146879.html

相关文章

【工具分享】Nessus一键转表格

项目地址&#xff1a;https://github.com/mashirohibiki/Nessus_to_csv 这个项目&#xff08;https://github.com/Bypass007/Nessus_to_report&#xff09;是5年前的老项目了&#xff0c;因为最近工作有做漏扫的工作&#xff0c;于是就找到了这样的项目&#xff0c;但是由于作…

当现代教育技术遇上仓颉---探秘华为仓颉编程语言与未来教育技术的接轨

引言 随着人工智能、物联网、区块链等新兴技术的发展&#xff0c;编程语言的需求也在不断演化。据市场研究机构发布的数据显示&#xff0c;全球编程语言市场规模预计在未来五年内将以每年10%的速度增长。此外&#xff0c;越来越多的企业和高校正在积极推动基于分布式系统和硬件…

JavaScript(五):JSON

目录 JSON是什么 JSON在JavaScript中的应用 将JavaScript对象转换为JSON字符串 将JSON字符串解析为JavaScript对象 JSON 与 JavaScript 对象的区别 JSON是什么 JSON是由键值对组成的数据集合&#xff0c;键key是一个字符串&#xff0c;值value可以是以下几种类型之一&…

前端单位 px、vw、vh 等的区别与使用场景

前端单位 px、vw、vh 等的区别与使用场景 在前端开发中&#xff0c;CSS中的长度单位至关重要&#xff0c;不同单位适用于不同的布局场景。以下是对常见单位的详细解析和使用建议。 1. px&#xff08;像素&#xff09; 概念&#xff1a;px是绝对单位&#xff0c;表示屏幕上的物…

PyTorch快速入门教程【小土堆】之优化器

视频地址优化器&#xff08;一&#xff09;_哔哩哔哩_bilibili import torch import torchvision from torch import nn from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential from torch.utils.data import DataLoaderdataset torchvision.datasets.CIFAR1…

线性代数概念整理笔记

一、基本概念 线性代数&#xff1a;是代数学的一个分支&#xff0c;主要处理线性关系问题。线性关系指的是数学对象&#xff08;比如方程中出现的未知数&#xff09;之间的关系是以一次形式来表达的。线性方程&#xff1a;含有n个未知量的一次方程。线性方程组&#xff1a;由多…

Spring Boot对访问密钥加解密——HMAC-SHA256

HMAC-SHA256 简介 HMAC-SHA256 是一种基于 哈希函数 的消息认证码&#xff08;Message Authentication Code, MAC&#xff09;&#xff0c;它结合了哈希算法&#xff08;如 SHA-256&#xff09;和一个密钥&#xff0c;用于验证消息的完整性和真实性。 HMAC 是 “Hash-based M…

!倒序数 !

时间限制&#xff1a;C/C 1000MS&#xff0c;其他语言 2000MS 内存限制&#xff1a;C/C 256MB&#xff0c;其他语言 512MB 难度&#xff1a;中等 分数&#xff1a;100 OI排行榜得分&#xff1a;12(0.1*分数2*难度) 描述 输入一个非负整数&#xff0c;输出这个数的倒序数。例如…