看下面这个例子:
#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)
is, afaik, completely valid, so it makes sense that, for any value given to ashared_ptr
, it'll call the deleter it's given, without wasting cycles checking if it'snullptr
- Phil M