c++11智能指针(二):shared_ptr和自定义的Deleter

本节讨论怎样使用 std::shared_ptr自定义Deleter.
当一个shared_ptr对象超出作用域时,其析构函数被调用,在析构函数中,将其引用计数减1,如果引用计数的值变为0,则删除关联的原始指针。
要删除析构函数中的内部原始指针,默认情况下,shared_ptr调用delete()函数,即

delete Pointer;
但是,我们在析构函数中并不总是要使用delete函数,还可能有其他的需求。

如果shared_ptr指向一个数组而不是一个简单的指针
std::shared_ptr<int> p3(new int[12]);
在其析构函数中,shared_ptr将会调用
delete
函数来删除int数组,而正确的方式是使用
delete []


增加定制deleter到shared_ptr
在这种情况下,我们可以将一个回调传递给shared_ptr的构造函数,该构造函数将会在其析构函数中被调用
定制Deleter作为函数指针
//函数调用接收到的指针上的delete[]
void deleter(Sample *x){
    std::cout<<"DELETE FUNCTION CALLED\n";
    delete[] x;
}


在shared_ptr的构造函数中传递函数指针,以提供自定义的deleter
//使用定制deleter创建sharedptr
std::shared_ptr<Sample> p3(new Sample[12, deleter);


检查完整的例子如下:

#include <iostream>
#include <memory>
 
struct Sample {
  Sample() {
    std::cout << "CONSTRUCTOR\n";
  }
  ~Sample() {
    std::cout << "DESTRUCTOR\n";
  }
};
 
//在接收到的指针上调用delte[]的函数
void deleter(Sample* x) {
  std::cout << "DELETER FUNCTION CALLED\n";
  delete[] x;
}
 
int main() {
  //使用定制的deleter创建shared_ptr
  std::shared_ptr<Sample> p3(new Sample[12], deleter);
  return 0;
}
输出:
CONSTRUCTOR
CONSTRUCTOR
CONSTRUCTOR
CONSTRUCTOR
CONSTRUCTOR
CONSTRUCTOR
CONSTRUCTOR
CONSTRUCTOR
CONSTRUCTOR
CONSTRUCTOR
CONSTRUCTOR
CONSTRUCTOR
DELETER FUNCTION CALLED
DESTRUCTOR
DESTRUCTOR
DESTRUCTOR
DESTRUCTOR
DESTRUCTOR
DESTRUCTOR
DESTRUCTOR
DESTRUCTOR
DESTRUCTOR
DESTRUCTOR
DESTRUCTOR
DESTRUCTOR

自定义Deleter作为lambda函数或函数对象
我们也可以将Function对象和Lambda函数作为回调函数来附加
class Deleter {
 public:
  void operator ()(Sample* x) {
    std::cout << "DELETER FUNCTION CALLED\n";
    delete[] x;
  }
};
 
//函数对象作为deleter
std::shared_ptr<Sample> p3(new Sample[12], Deleter());
 
//lambdah函数作为deleter
std::shared_ptr<Sample> p4(new Sample[12], [](Sample* x)
                           std::cout<<"DELETER FUNCTION CALLED\n";
                           delete[] x;
});

当我们不需要删除内存空间,只需要释放内存或资源给pool时,可能会有其他的情况。
查看一个虚拟实现 Memory Pool和Custom Deletor的例子:
#include <iostream>
#include <memory>
 
struct Sample {
};
 
//内存池虚拟类型的实现
template<typename T>
 
class MemoryPool {
 public:
  T* AquireMemory() {
    std::cout << "AQUIRING MEMORY\n";
    return (new T());
  }
 
  void ReleaseMemory(T* ptr) {
    std::cout << "RELEASE MEMORY\n";
    delete ptr;
  }
};
 
int main() {
  std::shared_ptr<MemoryPool<Sample>> memoryPoolPtr = std::make_shared<
                                                                           MemoryPool<Sample> >();
 
  std::shared_ptr<Sample> p3(memoryPoolPtr->AquireMemory(),
                             std::bind(&MemoryPool<Sample>::ReleaseMemory, memoryPoolPtr,
                                       std::placeholders::_1));
  return 0;
}
输出:
AQUIRING MEMORY
RELEASE MEMORY

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值