杂谈:智能指针与库

最近看一些库时发现仅指针一项就有挺多封装, 思考为什么需要智能指针?
通过智能指针可以以RAII的方式管理对象, 编写异常安全的代码; 原始的指针没有标明对象所有权的情况, 对象是你单独拥有的?还是你和别人共享对象, 但是你也参与管理? 还是你只是使用对象,但是没有所有权? 智能指针很好的解决了这些问题。

下面是一些常见的智能指针封装形式:

std::auto_ptr
基于所有权的智能指针,每次赋值或是拷贝构造都是所有权的转移,所以不能放到标准容器中。

unique_ptr
同样是基于所有权的智能指针,不支持赋值或是拷贝构造,但是因为C++11 Move语义和右值引用的支持,可以通过Move的方法放置到容器中。

proxy_ptr
仅是原始指针的封装代理,和普通指针没有什么区别, 不参与对象生命周期的管理。

ref_ptr (intrusive_ptr)
入侵式的引用计数智能指针,对象本身具有引用计数功能, 外部指针通过对象的引用计数管理该对象的生命周期。很多框架和库都是基于这种方式, 典型COM组件开发中的CComPtr就是这种类型的指针。

shared_ptr
非入侵式的引用计数智能指针,对象本身不需要计数功能,外部指针在创建对象时会自己创建计数功能并与对象绑定。这种方式使用起来非常方便,但是如果使用不当也会有很多问题, 具体参见shared_ptr四宗罪

weak_ptr
一般配合share_ptr一起使用, 因为weak_ptr本身不参与对象引用计数的管理,但是它能查询所引用的对象是否还有效, 所以通过weak_ptr可以解决循环引用的问题。

在写泛型代码的过程中,会有对程序失去控制的感觉,比如下面的代码:
//C++ 11
class
 bigclass {};

void fun(bigclass& b){}

int main()
{
   bigclass c;
   std::thread t(&fun, c);
   t.join();

    return 0;
}
你知道上面的c对象被拷贝了多少次吗? 如果改成std::ref(c)后呢?

我们用C写代码时可以明确知道每行代码最终汇编执行时的情况。
用经典C++(面向对象)写代码时, 如果C++基础扎实,也可以大概知道背后的汇编代码, 无非是多些构造,拷贝,赋值,析构,多态等。
但是用现代C++(面向对象+泛型), 你却很难知道最终展开后的汇编代码情况, 因为泛型与对方传的类型密切相关, 可能你一不小心,对象就被拷贝了N多份,而你还浑然不知。

越抽象的东西离底层机器就越遥远, C++隔着复杂的编译器, Java/C#隔着虚拟机, 脚本语言隔着解释器,也许 这就是高级语言的代价。

你可能感兴趣的:(杂谈:智能指针与库)