复合(has-a)、委托、继承(is-a)三种面向对象的关系机制—HJ-record06

目录

 

类与类之间有些什么关系?

Composition(复合关系):has-a

Composition(复合)关系下的构造与析构

Delegation(委托关系,Composition by reference)

Inheritance(继承关系):is-a

Inheritance(继承)关系下的构造和析构


类与类之间有些什么关系?

那么总结起来就三个:Composition(复合)、Delegation(委托)、Inheritance(继承)。

Composition(复合关系):has-a

下面先看一个模板里中抽出来的一段代码,

上面标黄的部分理解成一个和"deque<T>"一致的数据类型,为了阅读方便,直接将其进行替换,

这个意思表达的就是:在queue类中,有一个类型为“deque<T>”的变量c,这就是所谓的复合,口语化的讲就是,“我里面有另外一种东西”,详细点就是,在一个类中,含有其他类定义的对象在里面。表现出来就是一个类里面有一个(has-a)其他类定义的对象,当然也可以有多个。当代码量越来越多的时候,要习惯性的用图来表现,而不是用源代码,上图的右上角就是用图来表示这种关系。其中,queue类包含了deque类定义的对象,那么,queue类就加一个黑色的菱形符号来表示

当然这个例子也是特殊的,就是queue类所有的操作都是建立在deque上的,这是比较独特的。

Composition(复合)关系下的构造与析构

这个过程是编译器自动完成的。

下面的示意图,由于是左边的拥有右边的所以,左边的叫"Container",右边的叫"Component".从内存的角度看,就是右侧的浅蓝色的部分:

而当构造的时候,外界要先调用内部的默认构造函数,再执行自己(构造要由内而外);反过来,析构要由外而内,先执行自己的,再去调用内部的析构函数(析构的时候没有默认的概念)。上图中的标红部分,都是编译器自动加的,帮编程的语言尽量合理化。

Delegation(委托关系,Composition by reference)

由于类中带有指针,这个指针指向另外的一个类,这种就是所谓的委托关系。

通过右上角的图可以看见,一个空的菱形来表示这种关系,可以看出,这种关系这种关系有点虚,不是"实"的。

如果这种关系是用指针相连的,那就存在它们之间的生命周期不一致的问题。但是,这种设计方式非常的经典,就是我当前字符串该有什么东西(充当对外的接口),我不在这个对应的类写出来,我用其他类写出来(真正的实现),然后以委托的方式跟当前类建立关系。这种方式甚至可以称之为"编译防火墙",左边永远不用再编译,只需要编译右边就可以了!

那么在看上图下方的示意图,描述就是,多个对象,是由一个委托的类构造的,那么这个委托的类的关键功能,再由其他的类来具体的实现。

这里也有一个问题,由于a,b,c都是共享的"Hello"的内容,当然它们彼此之间是不知道的,那么,我们一定要保证,当修改a中的"Hello"内容的时候,不要去影响到b或者c的内容。所以,要确保该其中一个的时候,系统要单独拿(copy 的方式)一份数据给它改,而不影响其他的。改完之后,a独享一份数据,b,c共享一份数据。

Inheritance(继承关系):is-a

这里的struct可以理解成就是class,通过继承来实现另一个子类,右侧是对应的示意图。

这里面是借用继承的观念,子类可以去使用父类的数据,就好像子辈可以继承父辈的遗产。当然,这并不是继承最有价值的地方,继承的最有价值的地方,是跟虚函数结合使用的时候。

Inheritance(继承)关系下的构造和析构

这个过程是编译器自动完成的。

继承就是子类的对象里面有父类的成分在里头,也是一种外部包内部的结构,所以,参考复合关系中构造和析构函数的调用顺序,就可以理解了!

这里面也有一个良好的编程习惯要求:基类中的析构函数必须是虚函数,否则会出现undefined behavior。只要你认为你所设定的当前类要作为父类或将来要被作为父类使用,那就需要把其析构函数设定为虚函数使用(具体原因,下篇博客详解)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值