• C++11补充:智能指针如std::unique_ptr如何添加自定义的deleter


    关于智能指针的问题,有时候为了方便,需要在析构时附加一些清理操作,或者,有的指针本身来自C的库文件中,这时候,就非常期望能够使用自定义的deleter,

    但是标准C++创建函数如std::make_unique / std::make_shared 等不支持创建带有自定义deleter的智能指针,这时,我们只能使用自己的办法,

    1. #include
    2. #include
    3. class myclass {
    4. public:
    5. myclass() {
    6. std::cout << "myclass" << std::endl;
    7. }
    8. ~myclass() {
    9. std::cout << "~myclass" << std::endl;
    10. }
    11. void doSomething() {
    12. std::cout << "myclass is doing something" << std::endl;
    13. }
    14. };
    15. class A {
    16. public:
    17. A(){
    18. std::cout << "A" << std::endl;
    19. }
    20. ~A(){
    21. std::cout << "~A" << std::endl;
    22. }
    23. void doSomething() {
    24. std::cout << "A is doing something" << std::endl;
    25. }
    26. };
    27. struct my_creator_s {
    28. myclass* p = new myclass();
    29. A* a = new A();
    30. };
    31. struct my_deleter_s {
    32. void operator()(myclass* p) { delete p; }
    33. };
    34. struct my_deleter_s2 {
    35. void operator()(my_creator_s* s) { delete s->p; delete s->a; }
    36. };
    37. myclass* mycreator() {
    38. return new myclass();
    39. }
    40. void mydeleter(myclass* p){
    41. delete p;
    42. };
    43. int Test1() {
    44. std::cout << "----------------------------Test Method 1-----------------------------" << std::endl;
    45. myclass* myptr = new myclass;
    46. std::unique_ptrdecltype(&mydeleter)> ptr{ myptr, &mydeleter };
    47. ptr->doSomething();
    48. return 0;
    49. }
    50. int Test2() {
    51. std::cout << "----------------------------Test Method 2-----------------------------" << std::endl;
    52. std::unique_ptr ptr2 = std::unique_ptr(new myclass(), my_deleter_s());
    53. ptr2.get()->doSomething();
    54. return 0;
    55. }
    56. int Test3() {
    57. std::cout << "----------------------------Test Method 3-----------------------------" << std::endl;
    58. std::unique_ptr ptr3 = std::unique_ptr(new my_creator_s(), my_deleter_s2());
    59. ptr3.get()->a->doSomething();
    60. return 0;
    61. }
    62. int main() {
    63. Test1();
    64. Test2();
    65. Test3();
    66. return 0;
    67. }

     这段代码的输出如下,

    ----------------------------Test Method 1-----------------------------
    myclass
    myclass is doing something
    ~myclass
    ----------------------------Test Method 2-----------------------------
    myclass
    myclass is doing something
    ~myclass
    ----------------------------Test Method 3-----------------------------
    myclass
    A
    A is doing something
    ~myclass
    ~A

    说明:这里写了两个creator,函数mycreator没有用到;deleter一个采用了struct的办法,一个是采用了void函数的办法,大家可以自己尝试; 对于需要同时处理多个参数或变量的形式,建议采用struct或class的形式,Test Method3展示了如何使用creator或者说constructor创建的办法,写成这种方式是因为智能指针的deleter中只接受一个参数,例如,不能写成这样的,

    1. struct my_deleter_s2 {
    2. void operator()(myclass* p, A* a) { delete p; delete a; }
    3. };

    参考附录:

    Custom Deleter for C++ Smart Pointers - Lei Mao's Log Book

    本文结束

  • 相关阅读:
    在uniapp微信小程序中保存图片到本地相册
    openssl从证书中提取公钥
    # Jdk VisualVM使用、线程 dump 制作分析
    猿创征文 |《深入浅出Vue.js》打卡Day3
    子结点的数量(2)
    1.8 打好shell基础
    mapbox尝鲜值之云图动画
    C#设计原则
    元宇宙006 | 你不了解的“养成系”人工智能就此诞生
    ChessGPT:免费好用的国际象棋对弈AI机器人
  • 原文地址:https://blog.csdn.net/tanmx219/article/details/133078717