【问题标题】:Use case of smart pointers in stl data structuresstl 数据结构中智能指针的用例
【发布时间】:2016-11-27 20:36:29
【问题描述】:

我编写了这段代码来在堆上存储对象。工作正常......但我想知道“需要”或者更好的说法是编写这样的代码有什么好处。像 deque 这样的 STL 数据结构不是已经自动完成了我这里写的,也就是说,将对象存储在堆上吗?

如果不清楚,我使用的语法 data.push_back(shared_ptr(new Vehicle("aba"))); 使它在堆上存储对象,但不会 data.push_back(车辆(“aba”)); 默认情况下也这样做?

然后我可以将对数据结构的引用传递给函数,并且无论哪种方式都同样精简,不是吗?在这一点上,我质疑当存储的对象存储在 STL 数据结构中时,是否真的有任何用例来打扰智能指针。也许我应该让 C++ 自动管理它,然后将智能指针传递给数据结构本身,或者只是对它的引用。

        deque<shared_ptr<Vehicle>> data;
    data.push_back( shared_ptr<Vehicle>(new Vehicle("aba")) );
    data.push_back( shared_ptr<Vehicle>(new Vehicle("bobo")) );
    data.push_back( shared_ptr<Vehicle>(new Vehicle("cici")) );
    data.push_back( shared_ptr<Vehicle>(new Vehicle("dede")) );
    data.push_back( shared_ptr<Vehicle>(new Vehicle("efee")) );


    for(unsigned int i =0; i < data.size(); i++ )
    {
        cout << data.at(i)->getName() << endl;

    }

    data.pop_front();
    data.pop_back();


    for(deque<shared_ptr<Vehicle>>::iterator i = data.begin(); i != data.end(); )
    {
        cout << (*i)->getName() << endl;
        ++i;
    }

【问题讨论】:

  • 这取决于容器分配器。此外,如果您需要使用多态性,则需要(您自己的)指针。最后,容器中的数据不像std::shared_ptr那样是共享指针。

标签: c++ c++11 c++14


【解决方案1】:

使用deque&lt;Vehicle&gt; data; 的好处是您不必经过这么多抽象来获取数据。而且您的数据具有更好的访问位置。

缺点是您不能在其他列表/队列/变量中保存对它们的引用、指针或迭代器,因为每次擦除或插入风险都会使它们失效。

使用deque&lt;Vehicle *&gt; data; 将前一个翻转,您现在必须通过指向数据的指针,并且可能会丢失一些访问位置。 但是您现在可以将指针保存到其他地方的车辆。 但请注意,当您在某个位置删除车辆时,所有其他指针都将变为无效,并且如果访问会导致未定义的行为,例如崩溃。

使用deque&lt;shared_ptr&lt;Vehicle&gt;&gt; data; 以更多抽象为代价解决了最后一个问题。现在从一个队列中删除车辆不会使其在其他队列中无效。此外,它还提供了一个非常好的功能,即当最后一个对它的引用消失时,车辆会被删除。

shared_ptr 和原始指针都不能神奇地从所有列表或队列中删除车辆,如果您决定它应该全局消失。

【讨论】:

  • "缺点是您不能在其他列表/队列/变量中保存对它们的引用、指针或迭代器,因为每次擦除或插入都会使它们无效。" 不正确.根据容器,某些种类的“擦除或插入”操作会使它们无效。对于deque,前面或后面的插入/删除将永远使迭代器或引用/指针无效。对于list,插入/删除将永远使list 句点中的迭代器或引用无效。当然,除非您删除该特定项目。
  • 更改为“使它们无效的风险”。
  • 只有知识有限才有风险
  • @Sopel,如果可能的话,我希望避免在损坏数据的情况下犯错误的风险。
  • @Surt 您总是可以封装一个容器,只公开不会使运算符无效的函数,如果这比使用间接更好的话。它还将清楚地说明意图。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-02-01
  • 1970-01-01
  • 2016-04-12
  • 2014-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多