抽象数据类型之容器(三)

        本篇主要谈容器与其元素之间的关系,具体包括两个概念:直接容器与间接容器,容器元素的所有权。


一、直接容器与间接容器(点击打开链接

        英文原文是“Direct Container vs. Indirect Container”,英文中的“direct”有“直接的,直系的和指挥管理等含义”,在此取其形容词含义“直系的、直接的”,参考下面的英文定义。此外,Qt一书中的翻译为“托管的”,意思是“容器负责管理其元素”,与本书可能不是同一个概念,参看下图。

       Direct Containment 
       When an object is put into a container, a copy of that object is made in the container.
       Indirect Containment 
        When an object is put into a container, a pointer to that object is kept in the container.

        直接容器比较简单,比较容易理解和实现,存储的是元素对象的副本。但是它有3个缺点:1)占用内存空间大(要保存副本);2)添加或删除等操作效率低(需要copy);3)不能包含容器自身。

        间接容器保存的是指针,就没有直接容器的这三个缺点。它实际上是指针容器。(点击打开链接

注:在前面几篇文章中的抽象容器并没有添加删除元素的接口,是因为在定义这些接口时,需要选择“直接容器”或“间接容器”。




二、容器元素所有权

            针对指针容器,由于其存放的元素都是指针,究竟该由容器自动管理其元素指向的内存还是由外部user管理这些内存?
    如果由用户管理这些内存,则容器析构时,仅仅只需要将其包含的元素(指针)移出即可。Qt指针容器采用的就是这种设计,故“销毁Qt指针容器时,应调用qDeleteAll()函数”。
    如果由容器自动管理这些内存,容器销毁时,将逐个对其元素(指针)调用delete。即,在容器的析构函数中,调用qDeleteAll(*this)。前提是,这种类型的容器,其元素(指针)必须指向动态分配的内存空间,而不是静态全局的内存空间或stack空间。
    故在此,引入了Ownership(所有权)的概念,让用户来指定指针容器如何管理其元素指向的内存,即谁来调用析构函数。
    从前面的容器类的定义也可看出,容器既是一种Object,也有所有权。(多继承)


<span style="font-size:14px;">#ifndef OWNER_SHIP_H
#define OWNER_SHIP_H

class OwnerShip
{
public:
    void AssertOwnership() { isOwner = true; }
    void RescindOwnership() { isOwner = false; }
    bool IsOwner() { return isOwner == true; }

protected:
    OwnerShip() : isOwner(true) {}
    OwnerShip(OwnerShip & arg) : isOwner(arg.isOwner)
    {
        arg.isOwner = true;
    }
public:
    bool isOwner;
};

#endif // OWNER_SHIP_H</span>

        “Ownership”可以指定,也可以解除,此外在copy的时候,还可以转移。有了所有权的概念,我们可以像下面这样设计容器的清理函数。

<span style="font-size:14px;">void SomeContainer::Purge()  
{  
    if (IsOwner())  
        for each Object i in this container  
            delete &i;  
    Now clean up the container itself.  
}</span>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值