为什么带有自定义删除器的 unique_ptr 不适用于 nullptr,而 shared_ptr 却可以?

2024-04-28

使用简单的代码unique_ptr or shared_ptr作为瞄准镜守卫。有关要清除的内容的所有信息都记录在deleter,所以我认为使用是安全的nullptr对于构造函数。

显然,对于 Visual C++ 2017 (14.1),它无法按预期工作unique_ptr,但适用于shared_ptr。这是微软的怪癖,还是标准阻止调用deleter of a unique_ptr当持有nullptr?

在下面的代码中,我被迫构造一个unique_ptr with (void*)1。如果我用它构建它nullptr, cleaner不会被调用。为了shared_ptr, 没有区别,cleaner总是被调用。

#include <memory>
#include <iostream>

int main()
{
    int ttt = 77;

    auto cleaner = [&ttt](void*) {
        std::cout << "cleaner: " << ttt << "\n"; // do something with capture here instead of print
    };

    std::unique_ptr<void, decltype(cleaner)> p((void*)1, cleaner);

    std::shared_ptr<void> q(nullptr, [&ttt](void*) {
        std::cout << "shared: " << ttt << "\n"; // do something with capture here instead of print
    });

    std::cout << "done\n";
    return 0;
}

unique_ptr的析构函数需要这样做:

23.11.1.2.2 unique_ptr 析构函数 [unique.ptr.single.dtor]

2 效果:如果get() == nullptr没有影响。否则get_deleter()(get()).

实际上shared_ptr的析构函数需要执行相同的操作:

23.11.2.2.2 shared_ptr 析构函数 [util.smartptr.shared.dest]

— (1.1) 如果*this为空或与他人共享所有权shared_ptr实例 (use_count() > 1),没有副作用。

— (1.2) 否则,如果*this拥有一个对象 p 和一个删除器 d,调用 d(p)。

因此,依靠智能指针在作用域退出时执行任意操作并传递空指针是不可靠的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么带有自定义删除器的 unique_ptr 不适用于 nullptr,而 shared_ptr 却可以? 的相关文章

随机推荐