C++智能指针实例详解

2020-01-06 12:36:29于海丽

正确的代码应该为:


void TestAutoPtr3() {
 std::auto_ptr<Simple> my_memory(new Simple(1));
 if (my_memory.get()) {
  Simple* temp_memory = my_memory.release();
  delete temp_memory;
 }
}


void TestAutoPtr3() {
 std::auto_ptr<Simple> my_memory(new Simple(1));
 if (my_memory.get()) {
  my_memory.reset(); // 释放 my_memory 内部管理的内存
 }
}

原来 std::auto_ptr 的 release() 函数只是让出内存所有权,这显然也不符合 C++ 编程思想。
总结:std::auto_ptr 可用来管理单个对象的对内存,但是,请注意如下几点:

(1)    尽量不要使用“operator=”。如果使用了,请不要再使用先前对象。
(2)    记住 release() 函数不会释放对象,仅仅归还所有权。
(3)    std::auto_ptr 最好不要当成参数传递(读者可以自行写代码确定为什么不能)。
(4)    由于 std::auto_ptr 的“operator=”问题,有其管理的对象不能放入 std::vector 等容器中。
使用一个 std::auto_ptr 的限制还真多,还不能用来管理堆内存数组,这应该是你目前在想的事情吧,我也觉得限制挺多的,哪天一个不小心,就导致问题了。
由于 std::auto_ptr 引发了诸多问题,一些设计并不是非常符合 C++ 编程思想,所以引发了下面 boost 的智能指针,boost 智能指针可以解决如上问题。
让我们继续向下看。
 
3、boost::scoped_ptr

boost::scoped_ptr 属于 boost 库,定义在 namespace boost 中,包含头文件 #include<boost/smart_ptr.hpp> 便可以使用。boost::scoped_ptr 跟 std::auto_ptr 一样,可以方便的管理单个堆内存对象,特别的是,boost::scoped_ptr 独享所有权,避免了 std::auto_ptr 恼人的几个问题。
我们还是从代码开始分析:


void TestScopedPtr() {
 boost::scoped_ptr<Simple> my_memory(new Simple(1));
 if (my_memory.get()) {
  my_memory->PrintSomething();
  my_memory.get()->info_extend = "Addition";
  my_memory->PrintSomething();
  (*my_memory).info_extend += " other";
  my_memory->PrintSomething();
  
  my_memory.release();      // 编译 error: scoped_ptr 没有 release 函数
  std::auto_ptr<Simple> my_memory2;
  my_memory2 = my_memory;    // 编译 error: scoped_ptr 没有重载 operator=,不会导致所有权转移
 }
}

首先,我们可以看到,boost::scoped_ptr 也可以像 auto_ptr 一样正常使用。但其没有 release() 函数,不会导致先前的内存泄露问题。其次,由于 boost::scoped_ptr 是独享所有权的,所以明确拒绝用户写“my_memory2 = my_memory”之类的语句,可以缓解 std::auto_ptr 几个恼人的问题。