shared_ptr是新的标准库的一个主要成员,作为一个非嵌入式的智能指针,其设计可谓已经是绞尽脑汁。当然,还有很多人对它提出了不满。没有完美的设计,只有合适的设计。
1. shared_ptr最大的特点是接口的简单性与实现的灵活性。
对于shared_ptr<Object>,object的内存管理是可定制的,甚至可以定制引用计数结点的内存分配,以满足对内存有特殊要求的情况。而这一切,都被Object的实现者隐藏起来,使用Object的客户类是不用关心的。这和以前标准库的组件实现策略有些不同。比如说, vector<int, A1>和vector<int, A2>,由于内存分配策略的不同,而变成类型的不同,造成接口的改变。这一点在shared_ptr的设计时被避免了,当然以一定的性能代价。shared_ptr作为C++面向对象设计的一个重要组件,接口的简单性是很重要的,必须要有接口和实现的分离。与此相似的还有tr1::function的设计。
2.在同一体系中,各种类型的智能指针可以互相转换。
如下例:
struct Object : InterfaceA, InterfaceB {
MemberA memberA;
};
shared_ptr<Object> obj(new Object);
shared_ptr<InterfaceA> a = obj;
shared_ptr<InterfaceB> b = obj;
shared_ptr<Object> p = static_pointer_cast<Object>(b);
shared_ptr<void> p2 = obj;
甚至还可以取得数据成员的智能指针:
shared_ptr<Object> obj(new Object);
shared_ptr<MemberA> memberA(obj, &obj->memberA);
再来说说shared_ptr的缺点。
1.对于使用引用计数的智能指针来说,必须要小心出现循环引用。
在重度使用shared_ptr的系统中,你必须一开始就明确类与类的关系,以决定哪里使用shared_ptr,哪里使用weak_ptr,否则就会出现内存泄露。而
shared_ptr的接口转换的灵活性,也很容易导致智能指针被滥用。内存自动管理的问题并没有得到解决,它只是被转移了。
2.shared_ptr使用非嵌入式设计,这样可以使用于基本类型,比如 shared_ptr<int>。但是根据个人经验,这种情况在很少使用。大部分情况还是使用自己设计的类。这有一个问题,就是没有很方便的办法实现this指针和智能指针的转换。标准库中提供了enable_shared_from_this类来解决这个问题。但这已经使所谓的
非嵌入式设计徒有虚名。而假如一开始采用
嵌入式设计的话,则在性能代价和多线程设计方面具有更大的灵活性。