shared_ptr允许自定义一个Deleter

    1. #include <iostream>
    2. #include <memory>
    3. using namespace std;
    4. class T {
    5. private:
    6. static int id;
    7. int tid;
    8. public:
    9. T() {
    10. tid = id++;
    11. cout << "id = " << tid << " constructor called" << endl;
    12. }
    13. ~T() {
    14. cout << "id = " << tid << " destructor called" << endl;
    15. }
    16. };
    17. int T::id = 1;
    18. void delete_T(T *){
    19. cout << "delete T" <<endl;
    20. }
    21. int main() {
    22. cout << "--------begin-----------" << endl;
    23. {
    24. shared_ptr<T> t1(new T,delete_T);
    25. }
    26. cout << "--------end-----------" << endl;
    27. return 0;
    28. }

    image.png
    delete_T 中没有使用delete,t1的析构函数没有调用。

    正确做法

    1. #include <iostream>
    2. #include <memory>
    3. using namespace std;
    4. class T {
    5. private:
    6. static int id;
    7. int tid;
    8. public:
    9. T() {
    10. tid = id++;
    11. cout << "id = " << tid << " constructor called" << endl;
    12. }
    13. ~T() {
    14. cout << "id = " << tid << " destructor called" << endl;
    15. }
    16. };
    17. int T::id = 1;
    18. void delete_T(T *t){
    19. cout << "delete T" <<endl;
    20. delete t; // 在deleter中要手动delete
    21. }
    22. int main() {
    23. cout << "--------begin-----------" << endl;
    24. {
    25. shared_ptr<T> t1(new T,delete_T);
    26. }
    27. cout << "--------end-----------" << endl;
    28. return 0;
    29. }

    写成模板

    1. #include <iostream>
    2. #include <memory>
    3. using namespace std;
    4. class T {
    5. private:
    6. static int id;
    7. int tid;
    8. public:
    9. T() {
    10. tid = id++;
    11. cout << "id = " << tid << " constructor called" << endl;
    12. }
    13. ~T() {
    14. cout << "id = " << tid << " destructor called" << endl;
    15. }
    16. };
    17. int T::id = 1;
    18. template<typename _T>
    19. void delete_T(_T *t){
    20. cout << "delete T" <<endl;
    21. delete t;
    22. }
    23. int main() {
    24. cout << "--------begin-----------" << endl;
    25. {
    26. shared_ptr<T> t1(new T,delete_T<T>);
    27. }
    28. cout << "--------end-----------" << endl;
    29. return 0;
    30. }
    1. #include <iostream>
    2. #include <memory>
    3. using namespace std;
    4. class T {
    5. private:
    6. static int id;
    7. int tid;
    8. public:
    9. T() {
    10. tid = id++;
    11. cout << "id = " << tid << " constructor called" << endl;
    12. }
    13. ~T() {
    14. cout << "id = " << tid << " destructor called" << endl;
    15. }
    16. };
    17. int T::id = 1;
    18. void deleter1(T *t) {
    19. cout << "deleter 1" << endl;
    20. delete t;
    21. }
    22. void deleter2(T *t) {
    23. cout << "deleter 2" << endl;
    24. delete t;
    25. }
    26. int main() {
    27. cout << "--------begin-----------" << endl;
    28. {
    29. cout << 1 << endl;
    30. shared_ptr<T> t1(new T, deleter1);
    31. cout << 2 << endl;
    32. shared_ptr<T> t2(new T, deleter2);
    33. cout << 3 << endl;
    34. shared_ptr<T> t3 = t2;
    35. cout << 4 << endl;
    36. t2 = t1;
    37. cout << 5 << endl;
    38. }
    39. cout << "--------end-----------" << endl;
    40. return 0;
    41. }

    结果:
    image.png

    1. #include <iostream>
    2. #include <memory>
    3. using namespace std;
    4. class T {
    5. private:
    6. static int id;
    7. int tid;
    8. public:
    9. T() {
    10. tid = id++;
    11. cout << "id = " << tid << " constructor called" << endl;
    12. }
    13. ~T() {
    14. cout << "id = " << tid << " destructor called" << endl;
    15. }
    16. };
    17. int T::id = 1;
    18. void deleter1(T *t) {
    19. cout << "deleter 1" << endl;
    20. delete t;
    21. }
    22. void deleter2(T *t) {
    23. cout << "deleter 2" << endl;
    24. delete t;
    25. }
    26. int main() {
    27. cout << "--------begin-----------" << endl;
    28. {
    29. cout << 1 << endl;
    30. T * trow = new T;
    31. shared_ptr<T> t1(nullptr, deleter1);
    32. cout << 2 << endl;
    33. shared_ptr<T> t2(nullptr, deleter2);
    34. cout << 3 << endl;
    35. t1.reset(trow);
    36. cout << 4 << endl;
    37. t2=t1;
    38. cout << 5 << endl;
    39. }
    40. cout << "--------end-----------" << endl;
    41. return 0;
    42. }

    image.png
    似乎是只会绑定对象最初被创建时的那个deleter,同时 reset() 方法有一个可以指定deleter的重载