【发布时间】:2019-03-26 16:11:38
【问题描述】:
看这个例子:
#include <iostream>
#include <memory>
class Foo {
public:
Foo() { std::cout << "Foo()\n"; }
~Foo() { std::cout << "~Foo()\n"; }
};
int main(){
auto deleter = [](Foo* p) {
if(!p) { std::cout << "Calling deleter on nullptr\n"; }
delete p;
};
std::shared_ptr<Foo> foo;
std::cout << "\nWith non-null Foo:\n";
foo = std::shared_ptr<Foo>(new Foo, deleter);
std::cout << "foo is " << (foo ? "not ":"") << "null\n";
std::cout << "use count=" << foo.use_count() << '\n';
foo.reset();
std::cout << "\nWith nullptr and deleter:\n";
foo = std::shared_ptr<Foo>(nullptr, deleter);
std::cout << "foo is " << (foo ? "not ":"") << "null\n";
std::cout << "use count=" << foo.use_count() << '\n';
foo.reset();
std::cout << "\nWith nullptr, without deleter:\n";
foo = std::shared_ptr<Foo>(nullptr);
std::cout << "foo is " << (foo ? "not ":"") << "null\n";
std::cout << "use count=" << foo.use_count() << '\n';
foo.reset();
}
输出是:
With non-null Foo:
Foo()
foo is not null
use count=1
~Foo()
With nullptr and deleter:
foo is null
use count=1
Calling deleter on nullptr
With nullptr, without deleter:
foo is null
use count=0
这里我们看到shared_ptr 在使用nullptr 和自定义删除器初始化时调用了包含的删除器。
似乎,当使用自定义删除器初始化时,shared_ptr 认为它“拥有”nullptr,因此在删除任何其他拥有的指针时尝试删除它。虽然没有指定删除器时不会发生。
这是预期的行为吗?如果是这样,这种行为背后的原因是什么?
【问题讨论】:
-
delete(nullptr)是,afaik,完全有效,所以对于给定shared_ptr的任何值,它都会调用它给定的删除器,而不会浪费周期检查它是否是 @ 987654332@ -
Unlike std::unique_ptr, the deleter of std::shared_ptr is invoked even if the managed pointer is null.Source -
@PhilM 这实际上不是what the standard says,尽管根据 as-if 规则(当没有给出删除器时)它可能会像你描述的那样做
-
嗯,才发现stackoverflow.com/a/11164463/560648可能是骗子
标签: c++ shared-ptr smart-pointers reference-counting