类之间的复合关系
template <class T, class Sequence = deque<T> >
class queue {
...
protected:
Sequence c;
public:
// 以下完全利用 c 的操作函數完成
bool empty() const { return c.empty(); }
size_type size() const { return c.size(); }
reference front() { return c.front(); }
reference back() { return c.back(); }
void push(const value_type& x) { c.push_back(x); }
void pop() { c.pop_front(); }
};
以上的类可以用一种更加易于理解的表示方法:
template <class T>
class queue {
...
protected:
deque<T> c;
public:
bool empty() const { return c.empty(); }
size_type size() const { return c.size(); }
reference front() { return c.front(); }
reference back() { return c.back(); }
void push(const value_type& x) { c.push_back(x); }
void pop() { c.pop_front(); }
};
在复合关系可以表示为:
类构造由内而外,即Container的构造函数首先构造Component的默认构造函数,再执行自己的构造函数:
Container::Container(……):Component() { …… };
这种次序关系由编译器帮助完成,如果不想使用Component的默认构造函数,就要在构造时传递想要使用的Component构造形式。
类的析构是由外而内的,即Container先执行自己的析构函数,然后再调用Component的析构函数:
Container::~Container(……){ …… ~Component() };
内存关系可以表示为:
类之间的委托关系
class StringRep;
class String {
public:
String();
String(const char* s);
String(const String& s);
String &operator=(const String& s);
~String();
. . . .
private:
StringRep* rep; // pimpl
};
// file String.cpp
#include "String.hpp"
namespace {
class StringRep {
friend class String;
StringRep(const char* s);
~StringRep();
int count;
char* rep;
};
String::String(){ ... }
...
所谓的委托关系就是在一个类中包含了指向另一个类的指针,这种设计可以成为pointer to implementation,简称pimpl,即将接口和实现分离。这种设计的优点是可以实现引用计数:
有三个指针同时指向Hello,n是一个计数。
委托关系可以表示为:
继承
struct _List_node_base
{
_List_node_base* _M_next;
_List_node_base* _M_prev;
};
template<typename _Tp>
struct _List_node
: public _List_node_base
{
_Tp _M_data;
};
继承方式有三种:public,private,protected。
继承的关系可以表示为:
其中T表示使用了模板。这里的继承只是子类继承了父类全部的数据成员。
构造的由内而外,即先调用Base的构造函数,然后才执行自己的构造函数:
Derived::Derived(…): Base(){… };
析构由外而内,首先执行自己的析构函数,再调用Base的析构函数。
Derived::~Derived(…){ … ~Base() };
注意父类的析构函数必须是虚函数,否则会出现undefined behavior 。