Loading

侯捷c++课程笔记: 类之间的关系

OOD:object oriented design-relationships between classes

Composition 复合

表示 has a 的关系

template <class T>
class queue
{
protected:
    deque<T> c;
public:
    bool pop(){c.pop_front();}
    //... all implemented by deque
};

上面的一段代码既是Composition,也是一种设计模式 Adapter
queue的类中有一个deque,其中所有的function都是由deque实现,自己没有添加新的功能
这就好比变压器一样,将不同的电压进行转换。queue对deque的功能实现一定的改装,呈现出一种不同的效果。
Adapt:有适配,改写,修改的意思

sizeof(queue)分析

首先queue的大小即为deque的大小

template <class T>
class deque
{
protected:
    Itr<T> start;
    Itr<T> finish;
    T** map;
    unsigned int map_size;
};

deque有两个Itr和一个T**,一个unsigned int

template <class T>
struct Itr
{
    T* cur;
    T* first;
    T* last;
    T** node;
    //...
};

一个Itr内有四个指针,假设32位机器,则sizeof(queue)=2(44)+4+4=40

构造和析构

c++编译器处理好了执行的顺序

构造由内而外:Container的构造函数首先调用Component的default构造函数,然后执行自己
Container::Container(...) : Component() {...};
假如自己在外部类没有特别写出上面的格式,编译器自动生成如上格式,这里调用默认构造函数,因为是编译器自动决定的。而编译器并不知道应该调用哪种构造函数,所以选择调用默认的。如果想要指定调用,需要自己在外部的类的构造函数中指出。

析构由外而内:Container的析构函数首先执行自己,再调用Component的析构函数
Container::Container(...) {... ~Component()};

Delegation:Composition by reference

和复合的形式类似,只不过比较虚,因为拥有的不是实体,而是一个指针。
和Composition不同的一点是生命周期可能不同,可能等需要的时候才会创建Component

class StringRep
{
    int count;
    char* rep;
}
class String
{
    StringRep* rep;
}

上面这段是一种pimpl的实现,即pointer to implementation,也叫Handle/Body。存放指针的是handle,只定义一些接口,具体的实现放在body内。
这样做的一个好处是实现类的形式是可以切换的,实现的变动不影响客户端,具有一种弹性。

同时StringRep实现了reference counting,当String类进行拷贝时,指向的将会是同一份StringRep,实现了内存的共享。
但有一点要注意的是,当有多个共享时,其中一个pointer想要修改内容,需要复制一份给它修改,否则将会影响到其他pointer。这就是copy on write的思想。

Inheritance

表示 is a 的关系,有三种继承方式,一般采用public继承
父类的数据对象是会被继承下来的
标准库的一段继承

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;
}

内存的角度看,子类拥有父类的成分。构造和析构的方式和Composition一样,同样是编译器默认安排了
如果你认为一个类有可能成为父类,应该将其析构函数设置为virtual
因为你有可能需要用一个基类的指针指向一个子类的对象,在delete时,如果不设置为virtual,将不能调用到子类的析构函数

posted @ 2021-09-23 11:36  traver  阅读(56)  评论(0编辑  收藏  举报