gpt4 book ai didi

c++ - 为什么 std::shared_ptr 起作用

转载 作者:太空狗 更新时间:2023-10-29 23:15:15 25 4
gpt4 key购买 nike

我发现一些代码使用 std::shared_ptr 在关机时执行任意清理。起初我认为这段代码不可能工作,但后来我尝试了以下:

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

class test {
public:
test() {
std::cout << "Test created" << std::endl;
}
~test() {
std::cout << "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() ) );
std::cout << "Leaving scope" << std::endl;
}
std::cout << "Leaving main" << std::endl;
return 0;
}

这个程序给出了输出:

At begin of main.
creating std::vector<std::shared_ptr<void>>
Creating test
Test created
Leaving scope
Leaving main
Test destroyed

我对为什么这可能有效有一些想法,这与为 G++ 实现的 std::shared_ptrs 的内部结构有关。由于这些对象将内部指针与来自 std::shared_ptr<test> 的计数器一起包装至 std::shared_ptr<void>可能不会阻碍析构函数的调用。这个假设是否正确?

当然还有更重要的问题:这是否保证符合标准,或者可能会进一步更改 std::shared_ptr 的内部结构,其他实现实际上会破坏此代码?

最佳答案

诀窍在于 std::shared_ptr 执行类型删除。基本上,当一个新的 shared_ptr创建后它将在内部存储一个 deleter函数(可以作为构造函数的参数,但如果不存在则默认调用 delete )。当 shared_ptr被销毁,它调用存储的函数并将调用 deleter .

可以在此处看到使用 std::function 进行简化并避免所有引用计数和其他问题的类型删除的简单草图:

template <typename T>
void delete_deleter( void * p ) {
delete static_cast<T*>(p);
}

template <typename T>
class my_unique_ptr {
std::function< void (void*) > deleter;
T * p;
template <typename U>
my_unique_ptr( U * p, std::function< void(void*) > deleter = &delete_deleter<U> )
: p(p), deleter(deleter)
{}
~my_unique_ptr() {
deleter( p );
}
};

int main() {
my_unique_ptr<void> p( new double ); // deleter == &delete_deleter<double>
}
// ~my_unique_ptr calls delete_deleter<double>(p)

shared_ptr从另一个复制(或默认构造)删除器被传递,所以当你构造一个 shared_ptr<T> 时来自shared_ptr<U>关于调用什么析构函数的信息也在 deleter 中传递。 .

关于c++ - 为什么 std::shared_ptr<void> 起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30115809/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com