stl 数据结构中智能指针的用例
Use case of smart pointers in stl data structures
我编写这段代码是为了在堆上存储对象。工作正常......但我想知道 "need" 或者更好地说编写这样的代码有什么好处。像deque这样的STL数据结构不会自动完成我这里写的,也就是说,将对象存储在堆上吗?
如果不清楚,我使用的语法
data.push_back(shared_ptr(新车("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;
}
使用 deque<Vehicle> data;
的优点是您不必经过那么多抽象来获取数据。而且您的数据具有更好的访问位置。
缺点是您不能在其他 list/queues/variables 中保存对它们的引用、指针或迭代器,因为每次擦除或插入都有使它们失效的风险。
使用deque<Vehicle *> data;
颠覆了之前的做法,您现在必须通过指向数据的指针,并且可能会丢失一些访问局部性。
但是您现在可以在其他地方保存指向车辆的指针。
但是请注意,当您在一个地方删除车辆时,所有其他指针都会变得无效,并且如果访问会导致未定义的行为,例如崩溃。
使用deque<shared_ptr<Vehicle>> data;
以更多抽象为代价解决了最后一个问题。现在从一个队列中删除 Vehicle 不会使其在其他队列中无效。它还提供了一个非常好的功能,当最后一次引用消失时,车辆将被删除。
如果您决定它应该全局消失,shared_ptr
和原始指针都不能神奇地将车辆从它所在的所有列表或队列中删除。
我编写这段代码是为了在堆上存储对象。工作正常......但我想知道 "need" 或者更好地说编写这样的代码有什么好处。像deque这样的STL数据结构不会自动完成我这里写的,也就是说,将对象存储在堆上吗?
如果不清楚,我使用的语法 data.push_back(shared_ptr(新车("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;
}
使用 deque<Vehicle> data;
的优点是您不必经过那么多抽象来获取数据。而且您的数据具有更好的访问位置。
缺点是您不能在其他 list/queues/variables 中保存对它们的引用、指针或迭代器,因为每次擦除或插入都有使它们失效的风险。
使用deque<Vehicle *> data;
颠覆了之前的做法,您现在必须通过指向数据的指针,并且可能会丢失一些访问局部性。
但是您现在可以在其他地方保存指向车辆的指针。
但是请注意,当您在一个地方删除车辆时,所有其他指针都会变得无效,并且如果访问会导致未定义的行为,例如崩溃。
使用deque<shared_ptr<Vehicle>> data;
以更多抽象为代价解决了最后一个问题。现在从一个队列中删除 Vehicle 不会使其在其他队列中无效。它还提供了一个非常好的功能,当最后一次引用消失时,车辆将被删除。
如果您决定它应该全局消失,shared_ptr
和原始指针都不能神奇地将车辆从它所在的所有列表或队列中删除。