std :: shared_ptr为空,但不为空

问题描述 投票:0回答:3

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。我想保留此功能并使用其结果
c++ c++11 visual-c++ c++17 smart-pointers
3个回答
2
投票
您正在寻找的是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 }


1
投票
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(); }


0
投票
我是否可以创建一个空的std :: shared_ptr,即一个不拥有任何东西但不为null的东西,即包含有效载荷?

是。使用构造函数

template< class Y > shared_ptr(const shared_ptr<Y>&, element_type*);

如果将空的空共享指针作为第一个参数,将非空的指针作为第二个参数,则将得到一个空的非空共享的指针。

构造函数通常用于指向拥有对象的成员或别名,但恰好也与这种极端情况匹配。

根据您的情况:

wrapper = {std::shared_ptr<void>{}, p};

© www.soinside.com 2019 - 2024. All rights reserved.