c++0.4—–面向对象的三种关系(继承/复合/委托)

面向对象(OOD)(OOP):在研究复杂问题时,需要使类和类之间产生关系。分别为Inheritance(继承),Composition(复合),Delegation(委托)。

复合(composition):即一个类的中包含另一个类的成员。表示为has-a的关系

c++0.4-----面向对象的三种关系(继承/复合/委托)

例如:

文件名:

composition.h

 1 #ifndef __COMPOSITION__
 2 #define __COMPOSITION__
 3 #include <iostream>
 4 #include <deque>
 5 #include <vector>
 6 using namespace std;
 7 
 8 template <class T,class Sequence=deque<T>>
 9 class queue
10 {
11 private:
12     Sequence c;
13 public:
14     bool empty() const{return c.empty();}
15     vector<int>::size_type size() const {return c.size();}
16     //reference front(){return c.front();}
17     //reference back(){return c.back();}
18     void push(const vector<int>::value_type& x){c.push_back(x);}
19     void pop(){c.pop_front();}
20 };
21 #endif // __COMPOSITION_

  在类里面定义一个已经定义好的类的成员,这里deque<T>已经定义好了。这样在queue类里面可以通过c随意使用deque<T>的成员函数。

  在设计模式里,Adapter就是通过复合形成的,方法就是将已经设计好的类改造一下,例如将deque类的成员函数换一个名字。这样可以借助已经设计出来的类和接口,可以选择变量或者方法进行改装,封装成自己想到的类。上面这个例子就是Adapter的典型。

 

复合函数的调用顺序:

 例子:

文件名:composition.h

 1 #include <iostream>
 2 using namespace std;
 3 class B
 4 {
 5    public:
 6     B():b(){cout<<"construct a object B!!!"<<endl;}
 7     ~B(){cout<<"destruct a object B!!!"<<endl;}
 8 private:
 9     int b;
10 };
11 
12  
13 class A
14 {
15 public:
16     A(){cout<<"construct a object A!!!"<<endl;}
17     ~A(){cout<<"destruct a object A!!!"<<endl;}
18 private:
19     B c;
20     int a;
21 };

调用:

1 #include <iostream>
2 #include "composition.h"
3 using namespace std;
4 int main()
5 {
6     A a;
7     return 0;
8 }

此时结果为:

 c++0.4-----面向对象的三种关系(继承/复合/委托)

可见:构造函数调用顺序先里后外,析构函数的调用顺序是先外后里。

 

委托composition by referrence   Handle/Body  在设计模式中的应用为pImpl

c++0.4-----面向对象的三种关系(继承/复合/委托)

一个类的成员变量里面有另外一个类的指针,它的优点是可以跟别人共享一份资源。

并且调用和实现不在一起。叫做编译防火墙。

一个不好的例子:

文件名:delegation.h

 1 #include <iostream>
 2 using namespace std;
 3 
 4 class stringRep
 5 {
 6     friend class sstring;
 7 public:
 8     stringRep():count_n(0){cout<<"construct a objectStringRep"<<endl;}
 9     ~stringRep(){cout<<"destruct a objectStringRep"<<endl;}
10     stringRep(char* chr):count_n(0){this->chr=chr;cout<<"construct a objectStringRep"<<endl;}
11     char* getchr() const {return chr;}
12     int get_n() const {return count_n;}
13 private:
14     int count_n;
15     char* chr;
16 };
17 
18  
19 class sstring
20 {
21 public:
22     sstring(){cout<<"construct a objectSTRING"<<endl;}
23     sstring(stringRep& sr):rep(&sr){sr.count_n++;cout<<"construct a objectSTRING"<<endl;}
24     ~sstring(){(rep->count_n)--;cout<<"construct a objectString"<<endl;}
25 private:
26     stringRep* rep;
27 };

调用:

 1 #include <iostream>
 2 #include "delegation.h"
 3 using namespace std;
 4 
 5 int main()
 6 {
 7     stringRep sr("乌兹 never give up!!!");
 8     sstring str1(sr);
 9     sstring str2(sr);
10     sstring str3(sr);
11     cout<<endl<<"count_n="<<sr.get_n()<<endl<<endl;
12     cout<<sr.getchr()<<endl<<endl;
13     return 0;
14 }

运行结果:

 c++0.4-----面向对象的三种关系(继承/复合/委托)

注意:之所以说这个例子不好,因为虽然这里包含了类的指针,也即是委托。但是它并不是纯粹的pImpl模式,因为sstring类里面还是包含了stringRep的成员,做这个例子只是为了实现count_n的功能而已,即表示多少sstring对象指向一个stringRep对象。

 

继承 父类的数据完全地被继承下来。表示is-a(是一种)的关系

c++0.4-----面向对象的三种关系(继承/复合/委托)

例如:

文件名:inheritance.h

 1 #include<iostream>
 2 using namespace std;
 3 class A
 4 {
 5 public:
 6     A(){cout<<"construct a objectA"<<endl;}
 7     ~A(){cout<<"destruct a objectA"<<endl;}
 8 };
 9 
10 
11 class B:public A
12 {
13 public:
14     B(){cout<<"construct a objectB"<<endl;}
15     ~B(){cout<<"destruct a objectB"<<endl;}
16 };

调用:

1 #include <iostream>
2 #include "inheritance.h"
3 using namespace std;
4 
5 int main()
6 {
7     B b;
8     return 0;
9 }

运行结果:

c++0.4-----面向对象的三种关系(继承/复合/委托)

 表示构造函数调用的顺序是先父后子,析构的顺序是先子后父。

 

虚函数和非虚函数和纯虚函数:

非虚函数:不希望子类重写(override)的父类函数。但是若子类强行要重写,那也不会报错。

例如:

 

int getvalue() const {return value;}

 

虚函数:希望子类进行重写的父类成员函数。在父类中有实现。

例如:

virtual int getvalue() const {return value;}

纯虚函数:要求子类必须重写,否则报错。

例如:

 

virtual int getvalue() const =0;

 

原文链接: https://www.cnblogs.com/yulianggo/p/9276359.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    c++0.4-----面向对象的三种关系(继承/复合/委托)

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/277217

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月15日 上午2:23
下一篇 2023年2月15日 上午2:25

相关推荐