【问题标题】:Raw pointer vs smart-pointer in C++11 [duplicate]C ++ 11中的原始指针与智能指针[重复]
【发布时间】:2019-06-30 22:22:11
【问题描述】:

我试图了解如何将 C++ 软件上的原始指针替换为智能指针。

我有以下代码:

class Foo
{
private:
    std::vector<Bar *> m_member;
};

现在在某个函数中,我使用以下内容填充该向量:

m_member.push_back( new Bar() );

当我的程序完成时,我删除内存:

for( std::vector<Bar *>::iterator it = m_member.begin(); it < m_member.end(); ++it )
{
    delete (*it);
    (*it) = NULL;
}

现在这一切都很好。

问题在于我看到它来自这样一个事实,即在某个时间点我可能需要从向量中删除一个成员(该成员是用户指定的)。

现在这很容易:

for(...)
{
    if( (*it)->GetFieldFromBar() == <user_specified_condition> )
    {
        delete (*it);
        (*it) = NULL;
    }
}

但是我如何用智能指针重写它呢?有可能吗?

【问题讨论】:

  • 你试过什么?将std::vector&lt;Bar *&gt; m_member; 更改为std::vector&lt;std::unique_ptr&lt;Bar&gt;&gt; m_member; 应该很容易。然后,如果您需要删除一个元素,您只需 erase 即可。
  • (在这种情况下,我实际上会使用 unique_ptr 而不是 shared_ptr)。
  • 为什么要指针,std::vector&lt;Bar &gt; 还不够吗?

标签: c++ c++11 pointers smart-pointers


【解决方案1】:

使用智能指针实际上要容易得多,这里是unique_ptr

人口是通过:

m_member.push_back(std::make_unique<Bar>()); // C++14, you can use std::unique_ptr<Bar>(new Bar) is you only have C++11

不需要析构函数。

自定义删除:

for(auto& p: m_member)
{
    if( p->GetFieldFromBar() == <user_specified_condition> )
    {
        p.reset();
    }
}

【讨论】:

  • 只是指出,std::make_unique 是一个 c++14 函数。
  • @AdamBrinded 非常好。想了想忘记加了。
  • 值得检查的是,如果您的特定项目的编译器支持 c++11 中的 make_unique。如果是这样,那么 make_unique 可能更可取。
  • 现在自定义删除可能会使用erase-remove idiom :)
  • @Jarod42 取决于,OP 似乎不想删除条目本身。至少不是他给我们看的。
【解决方案2】:

是的,在这种情况下使用std::vector&lt;std::unique_ptr&lt;Bar&gt;&gt; 是理想的选择。您显然拥有向量的所有权。

在c++14中可以通过以下方式添加元素:

m_member.push_back( std::make_unique<Bar>() );

删除所有元素会减少到:m_member.clear(),甚至只是让它超出范围。

有选择地删除元素最好这样做:

m_member.erase(std::remove_if(m_member.begin(), m_member.end(), [&](auto &&ptr) { return ptr->GetFieldFromBar() == <user_specified_condition>; }), m_member.end());

不过,对于处理所有元素有点描述性,您可以将其包装在一个函数中以摆脱样板。

【讨论】:

  • 问题标有c++11,而不是c++14。这是否意味着构造函数将是m_member.push_back( std::unique_ptr&lt;Bar&gt;( new Bar() ) )
  • 或者emplace_back(new Bar());除非你使用像 absail 这样的库,或者你的 STL 在 c++11 模式下也暴露了这一点
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-03-10
  • 1970-01-01
  • 2016-08-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-23
  • 1970-01-01
相关资源
最近更新 更多