快速笔记:std::shared_ptr

https://stackoverflow.com/questions/5913396/why-do-stdshared-ptrvoid-work

description

  • shared_ptr 构造时保留了析构函数指针

  • 理论上子类析构可以没有 virtual 关键字,但是不建议

  • 因为C语言的习惯,还是觉得 std::shared_ptr<void> 不应是个好的选择

  • std::unique_ptr<void> 并不能做到 std::shared_ptr<void> 相同的效果,这是因为默认删除器(std::default_delete<T>)是针对完全类型的

    1
    2
    3
    4
    5
    6
    template<typename T>
    struct default_delete {
    void operator()(T* ptr) const {
    delete ptr;
    }
    };
1
2
3
4
5
6
7
8
9
10
11
std::unique_ptr<void> ptr(new int(42)); // 错误!
// error: invalid application of ‘delete’ to incomplete type ‘void’

// 使用 lambda 表达式定义删除器
auto deleter = [](void* ptr) {
std::cout << "Custom lambda deleter called for pointer: " << ptr << std::endl;
free(ptr); // 使用 free 释放内存
};

// 创建 std::unique_ptr<void>,使用 lambda 删除器
std::unique_ptr<void, decltype(deleter)> ptr(malloc(100), deleter);

code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85

#include <memory>
#include <iostream>
#include <vector>

class test {
public:
test() {
std::cout << "Test created" << std::endl;
}
virtual ~test() {
std::cout << "Test destroyed" << std::endl;
}
};

class sub_test : public test {
public:
sub_test() {
std::cout << "sub_test created" << std::endl;
}
virtual ~sub_test() {
std::cout << "sub_test destroyed" << std::endl;
}
};

int main() {
std::cout << "At begin of main.\ncreating std::vector<std::shared_ptr<void>>"
<< std::endl;
std::vector<std::shared_ptr<void>> v;
{
std::cout << "Creating test" << std::endl;
v.push_back( std::shared_ptr<test>( new test() ) );
v.push_back( std::shared_ptr<test>( new sub_test() ) );
std::cout << "Leaving scope" << std::endl;
}

std::cout << "-------------1" << std::endl;
v.pop_back(); // sub_test pop out
std::cout << "-------------2" << std::endl;
v.pop_back(); // test pop out
std::cout << "-------------3" << std::endl;

// std::unique_ptr<void>
auto test_st_deleter = [](void* ptr) {
std::cout << "test struct deleter." << std::endl;
// anything check ptr's type
auto st_ptr = static_cast<test*>(ptr);
if (st_ptr) {
delete st_ptr;
ptr = nullptr;
return;
}
// anything else....
};
{
std::cout << "Creating unique test" << std::endl;
std::unique_ptr<void, decltype(test_st_deleter)> u_ptr(new sub_test(), test_st_deleter);
std::cout << "Leaving unique scope" << std::endl;
}
std::cout << "Leaving main" << std::endl;
return 0;
}

// output
At begin of main.
creating std::vector<std::shared_ptr<void>>
Creating test
Test created
Test created
sub_test created
Leaving scope
-------------1
sub_test destroyed
Test destroyed
-------------2
Test destroyed
-------------3
Creating unique test
Test created
sub_test created
Leaving unique scope
test struct deleter.
sub_test destroyed
Test destroyed
Leaving main
------ 本文结束 ------
------ 版权声明:转载请注明出处 ------