一般什么时候用类的组合,什么时候用类的继承

huhaifengasd 2012-02-19 06:53:38
如题 C++新手、求解释
...全文
1183 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
cxyOOOO 2012-02-22
  • 打赏
  • 举报
回复
继承偏重集体,具有特殊性的集体(派生类)可以看作是一般性集体(基类)的一部分,如汽车对于交通工具。
组合偏重个体,某个功能对象被宿主对象看成自己的一部分,如轮子对于汽车。

与看待事物的角度有关,继承偏抽象,组合偏具体。
pathuang68 2012-02-21
  • 打赏
  • 举报
回复
Boy说得很好。一般情况下,除非必要,通常的原则是优先考虑使用组合
coding_leezam 2012-02-21
  • 打赏
  • 举报
回复
见书:effective c++,more effective c++,exceptional c++,组合就是has,继承是is,
Wolf0403 2012-02-21
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 pengzhixi 的回复:]

引用 12 楼 loaden 的回复:
引用 9 楼 supermegaboy 的回复:
这里说的“实现”指的是类对象的内存映象,方法指的是成员函数。
这句没看懂,求教?


他说的实现就是指数据成员
[/Quote]
那不就更是错的了?对于 private 数据成员来说,组合和继承都无法访问,关键点根本不在这里么。
支持英文数字 2012-02-21
  • 打赏
  • 举报
回复
简单的说,组合是指有一个,继承是指是一个。
qscool1987 2012-02-21
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 pengzhixi 的回复:]
引用 12 楼 loaden 的回复:
引用 9 楼 supermegaboy 的回复:
这里说的“实现”指的是类对象的内存映象,方法指的是成员函数。
这句没看懂,求教?


他说的实现就是指数据成员
[/Quote]
数据成员也能称为实现?实现和方法如何还能有区别?
我的理解:组合体现为实现层面,继承主要体现在扩展方面
我觉得如果并不是需要一个类的所有东西(包括接口和属性),那么就不需要用继承,相反就用组合。
用继承那就必须是所有的都继承,不是所有的都继承,那么就是滥用继承。
pengzhixi 2012-02-21
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 loaden 的回复:]
引用 9 楼 supermegaboy 的回复:
这里说的“实现”指的是类对象的内存映象,方法指的是成员函数。
这句没看懂,求教?
[/Quote]

他说的实现就是指数据成员
「已注销」 2012-02-21
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 supermegaboy 的回复:]
这里说的“实现”指的是类对象的内存映象,方法指的是成员函数。[/Quote]
这句没看懂,求教?
Wolf0403 2012-02-21
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 supermegaboy 的回复:]
当你需要它的实现而非方法的时候,应使用继承;当你需要它的方法而非实现的时候,应使用组合;

这里说的“实现”指的是类对象的内存映象,方法指的是成员函数。
[/Quote]
更模糊了。
不管是
struct A : B {}
还是
struct A { B m_b; }
通过组合和继承你都是将一个 B 类对象完整地嵌入一个 A 类对象中。唯一不同的是,通过继承,A 类对象得到了 B 类的所有公开接口供外界调用,而组合的时候,A 的公开接口并没有发生变化。
zzcmx2008 2012-02-21
  • 打赏
  • 举报
回复
dahaiI0 2012-02-21
  • 打赏
  • 举报
回复
马那个克,慢慢消化,高手好多啊
mosal 2012-02-21
  • 打赏
  • 举报
回复
Model "has-a" or "is-implemented-in-terms-of" through composition
Use private inheritance judiciously
FrankHB1989 2012-02-21
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 qscool1987 的回复:]

引用 13 楼 pengzhixi 的回复:
引用 12 楼 loaden 的回复:
引用 9 楼 supermegaboy 的回复:
这里说的“实现”指的是类对象的内存映象,方法指的是成员函数。
这句没看懂,求教?


他说的实现就是指数据成员

数据成员也能称为实现?实现和方法如何还能有区别?
我的理解:组合体现为实现层面,继承主要体现在扩展方面
我觉得如果并不是需要一……
[/Quote]
private数据成员就算实现,PImpl除外。
由于PImpl,组合在编译依赖和不同版本的运行时兼容性上优于继承;由于mixin,继承在合理复用实现的潜力优于组合。两者的合理使用都需要经验积累,不过感觉用好mixin比用好PImpl难许多。
最终还是看需求决定。

FrankHB1989 2012-02-21
  • 打赏
  • 举报
回复
不是所有的继承是“是一个”。public继承才是“是一个”。
组合在外部来看近似private继承,除了继承可以使用虚函数。如果不使用虚函数一般优先考虑组合以免各种隐式使用基类成员闪瞎眼;不过继承有时候可以少写不少代码,反而更清楚。
铁文 2012-02-21
  • 打赏
  • 举报
回复
类之间有三种关系:is-a;has-a,用-实现;
is-a;has-a的关系从逻辑上通常很好区分,此处不谈。

现在假设,A类要使用B类实现一些操作;此时,可以使用私有继承和组合,那么到底选用哪个呢?
标准答案是优先使用组合,因为它具有更好的封装性,应变能力强。
但是,当B涉及多态或其它特殊理由的时候(比如,B是一个结构,并明确要求需要对A进行B的切片),就必须使用私有继承。
飞天御剑流 2012-02-20
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 wolf0403 的回复:]

引用 6 楼 supermegaboy 的回复:

可以给你一个适用于多数情况(但非绝对)的原则:

当你需要它的实现而非方法的时候,应使用继承;当你需要它的方法而非实现的时候,应使用组合;

无论什么时候,组合应比继承优先考虑,因为继承有损松散耦合度。

啥叫实现,啥叫方法?没看懂。。
[/Quote]
这里说的“实现”指的是类对象的内存映象,方法指的是成员函数。
飞天御剑流 2012-02-20
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 jenicooper 的回复:]

尽量用组合。
[/Quote]
尽量用组合是错的,应该说优先考虑组合。
Wolf0403 2012-02-20
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 supermegaboy 的回复:]

可以给你一个适用于多数情况(但非绝对)的原则:

当你需要它的实现而非方法的时候,应使用继承;当你需要它的方法而非实现的时候,应使用组合;

无论什么时候,组合应比继承优先考虑,因为继承有损松散耦合度。
[/Quote]
啥叫实现,啥叫方法?没看懂。。
飞天御剑流 2012-02-20
  • 打赏
  • 举报
回复
可以给你一个适用于多数情况(但非绝对)的原则:

当你需要它的实现而非方法的时候,应使用继承;当你需要它的方法而非实现的时候,应使用组合;

无论什么时候,组合应比继承优先考虑,因为继承有损松散耦合度。
jenicooper 2012-02-19
  • 打赏
  • 举报
回复
尽量用组合。
加载更多回复(4)
源码下载地址: https://pan.quark.cn/s/c20c5da6957d 卸载 首先,需要核实是否存在先前安装的记录,或者系统是否预置了httpd服务,可通过以下命令进行验证: # rpm -qa | grep httpd 或者: # yum list | grep httpd 我之前已经进行过一次安装,因此在此会看到相应的显示结果: 然后我将着手卸载我的httpd,首要步骤是终止httpd服务的运行,对应的命令如下: # systemctl stop httpd.service 接着,无论是使用 rpm -e 还是 yum -erase 命令均可实现卸载,但需注意使用rpm -e命令前必须自行移除相关依赖包,因此我选择使用yum -erase命令进行卸载,具体命令为: # yum erase httpd.x86_64 在执行过程中会提示确认操作 在Linux环境中,CentOS 7 是一种非常普遍的操作系统,特别是在服务器应用方面。Apache HTTP Server(通常简称为Apache或httpd)是最广受欢迎的网页服务器软件之一,主要用于承载网站及相关服务。本资源将详尽说明在CentOS 7系统中关于Apache服务的安装与移除流程。 ### 移除Apache服务 1. **核实安装情况**: 在执行卸载操作前,必须先确认Apache是否已安装。这可以通过查询已安装的软件包列表来完成,可选用以下任一命令: ```bash # rpm -qa | grep httpd # yum list | grep httpd ``` 若Apache已安装,上述命令将返回相关的软件包信息。 2. **终止服务运行**: 在卸载前,必须先停止正在运行的A...
下载代码方式:https://pan.quark.cn/s/a4b39357ea24 在信息技术行业,特别是在操作系统部署及维护方面,统一可扩展固件接口(UEFI)与Linux系统如Debian的相互配合是一个关键议题。本篇将深入分析"在Debian 9.13系统中通过UEFI启动的UEFI Shell"这一焦点,并阐述如何处理安装期间遭遇的启动障碍。 UEFI作为替代传统BIOS的新型固件架构,它带来了更为先进、更为安全的启动机制,同时支持更大容量的存储设备以及更迅捷的启动时间。在部署Debian 9.13(Stretch版本)时,用户可以选择运用UEFI模式进行安装,从而获取上述种种好处。然而,UEFI启动过程需要特定的引导管理器,一般而言是GRUB2的UEFI版本,即称作grubx64.efi。 描述中所述情形可能是由于安装阶段GRUB2引导管理器的UEFI版本未能被恰当地生成或设置,因而系统无法经由UEFI模式启动。在此情形下,"uefishell"工具便显得尤为重要。UEFI Shell是一个命令行界面,它允许用户在UEFI环境中执行多样任务,包括手动引导操作系统。它提供了一个临时的补救措施,使用户得以纠正引导故障。 为了借助UEFI Shell来纠正启动故障,必须遵循以下步骤: 1. **获取UEFI Shell**:通常,UEFI Shell作为现代计算机UEFI固件的一部分预先安装,但在某些情况下,可能需要从设备制造商的官方网站上获取最新版本。 2. **插入搭载UEFI Shell的USB存储设备**:将下载的UEFI Shell文件拷贝至一个采用FAT32格式化的USB存储设备上,并将其接入计算机。 3. **进入UEFI配置界面**:重新...

65,213

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧