http://www.cplusplus.com/reference/memory/shared_ptr/说
不拥有任何指针的shared_ptr称为空的shared_ptr。指向无对象的shared_ptr称为null shared_ptr,并且不得取消引用。注意,尽管空的shared_ptr不一定是空的shared_ptr,而null的shared_ptr不一定是空的shared_ptr。
我是否可以创建一个空的std :: shared_ptr,即一个不拥有任何东西但不为null的东西,即包含有效载荷?
用例是将“旧式”代码与现代指针结合在一起:鉴于foo
的调用语法不会更改,
void foo(const MyClass* p) {
if (p == nullptr) {
auto defaultObject = std::make_shared<MyClass>("some", "parameters");
defaultObject->doSomething();
...
defaultObject->doSomethingElse();
// The default object must be destroyed again
} else {
p->doSomething();
...
p->doSomethingElse();
// p must not be destroyed, its memory is managed somewhere else
}
}
doNotOwnButStillPointTo()
是否有实现此功能的方法:
void foo(const MyClass* p) {
std::shared_ptr<MyClass> wrapper;
if (p == nullptr) {
// Create a default object
wrapper = std::make_shared<MyClass>("some", "parameters");
} else {
wrapper = doNotOwnButStillPointTo(p);
}
wrapper->doSomething();
...
wrapper->doSomethingElse();
// p mus not be destroyed, the default object (if created) shall be
}
或者,为了不落入XY-Problem,有没有其他可用的智能指针或根本没有?
std::make_shared<MyClass>("some", "parameters")
行实际上是对一个更复杂的函数的调用,该函数创建了shared_ptr。我想保留此功能并使用其结果shared_ptr
的自定义删除程序构造器。它的构建旨在允许共享指针从其他位置接管指针,当它被销毁时,它将运行您的自定义代码,而不是调用delete。在这种情况下,自定义代码将什么都不做,因为您不想删除指针。看起来像void foo(const MyClass* p) {
std::shared_ptr<MyClass> wrapper;
if (p == nullptr) {
// Create a default object
wrapper = std::make_shared<MyClass>("some", "parameters");
} else {
wrapper = std::shared_ptr(p, [](auto){ });
}
wrapper->doSomething();
...
wrapper->doSomethingElse();
// p mus not be destroyed, the default object (if created) shall be
}
shared_ptr
有一个deleter。这是销毁基础对象的多态过程。您可能有一个空的删除器:
void foo(const MyClass* p) {
std::shared_ptr<MyClass> wrapper;
if (p == nullptr) {
// Create a default object
wrapper = std::make_shared<MyClass>("some", "parameters");
} else {
wrapper = std::shared_ptr<MyClass>(p, [](MyClass*){});
}
wrapper->doSomething();
...
wrapper->doSomethingElse();
// p mus not be destroyed, the default object (if created) shall be
}
但是,这会导致设计不良。回到问题XY:目的是什么?有人可能向您传递一个对象作为原始指针(但可能会传递nullptr)。您希望在提供nullptr而不是实际对象的情况下创建本地。您可能希望防止内存泄漏。好。
void foo(const MyClass* p) { std::shared_ptr<MyClass> local; if (p == nullptr) { // Create a default object local = std::make_shared<MyClass>("some", "parameters"); p = local.get(); } // p is always valid, local will always be destroyed (if exists) p->doSomething(); ... p->doSomethingElse(); }
我是否可以创建一个空的std :: shared_ptr,即一个不拥有任何东西但不为null的东西,即包含有效载荷?
是。使用构造函数
template< class Y >
shared_ptr(const shared_ptr<Y>&, element_type*);
如果将空的空共享指针作为第一个参数,将非空的指针作为第二个参数,则将得到一个空的非空共享的指针。构造函数通常用于指向拥有对象的成员或别名,但恰好也与这种极端情况匹配。
根据您的情况:
wrapper = {std::shared_ptr<void>{}, p};