Effective STL 读书笔记 2

Item 10:注意 allocator 的惯例和限制。
  • Allocator 最初是为了对在16位系统上的 near 和 far 指针内存访问模式进行抽象而加入的(虽然这个尝试失败了),之后 Allocator 被设计成为标准库提供全攻能的内存管理模块。但由于效率问题,标准委员会弱化了 Allocator 的功能。甚至打多数的 container 根本就不使用 allocator,也因此有了:“allocator is weird”。
  • 由于标准的限制在实现 allocator 时你必须定义(typedef) allocator<T>::pointer 和 allocator<T>::reference,而且必须定义为 T* 和 T&。
  • Allocator 是弱化的对象,标准规定:同一个的类型(T)的所有 allocator<T> 对象必须等价并且其比较函数必须返回真,这就意味着 Allocator 对象不能拥有自己的 data member,所有的数据必须都是 static 的。也就意味着对同一种类型的存储不能有两个堆,这主要是为了,实现 node based container 的 splice 等函数。考虑如下代码:
template<typename T>
class MyAllocator {...};

std::list<Item, MyAllocator<Item> > listA;
std::list<Item, MyAllocator<Item> > listB;

listA.splice(listB.begin(), listB);
  • pointer allocator<T>::allocate(size_type numObjects) 的参数是对象的数量,而不是size。返回值是 T*,但是T*并不指向一个T objects,因为T并没有被构造,仅仅是分配了一块内存。在 node based container 中,动态分配的是节点 node<T>,而不是 T object,标准库采用了如下代码来实现这个功能:
template<typename T>
class MyAllocator {
public:
    template<typename Node>
    struct rebind {
        typedef allocator<Node> other;
    };
};


Item 11:理解自定义 allocator 的正确用途。
  • 当需要自定义容器内对象的内存布局时。
  • 可用如下方法为同种类型对象创造不同的堆:
class Heap1 {
public:
    static void *alloc(...) {...}
    static void *dealloc(...) {...}
};
class Heap2 {
public:
    static void *alloc(...) {...}
    static void *dealloc(...) {...}
};
template<typename T, typename Heap>
class MyAllocator {
public:
    pointer allocate(...) {
       //use Heap::alloc;
    };
    void deallocate(...) {
       //use Heap::dealloc;
    };
};
vector<int, MyAllocator<int, Heap1> > v1;
vector<int, MyAllocator<int, Heap2> > v2;
  • 注意上文中 Heap 是类型而不是对象。

Item 12:不要对 STL 的线程安全性有任何期望。
  • 在多线程环境中,使用 Lock Object 方法锁定关键代码:
vector<int> v;
{
    Lock<vector<int> > lock(v);
    //other operation on vector v;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值