我正在为我的应用程序设计一个类,它实现了许多标准的共享指针和标准容器的使用,例如std :: map和std :: vector
这是问题的非常具体的问题,所以我只是为了澄清目的从我的标题中复制了一段代码.这里是标题中声明的快照:
struct Drag;
std::map<short, std::shared_ptr<Drag>> m_drag;
typedef sigc::signal<void, Drag&> signal_bet;
inline signal_bet signal_right_top();
Run Code Online (Sandbox Code Playgroud)
这是使用上述声明的函数之一和临时的shared_ptr,它不仅用于此函数,还用于某个较晚的时间.这意味着在函数返回后,共享指针仍应处于活动状态,因为它将在某个时刻分配给另一个shared_ptr.
void Table::Field::on_signal_left_top(Drag& drag)
{
m_drag.insert(std::make_pair(drag.id, std::make_shared<Drag>(this))); // THIS!
auto iter = m_drag.find(drag.id);
*iter->second = drag;
iter->second->cx = 0 - iter->second->tx;
iter->second->cy = 0 - iter->second->ty;
invalidate_window();
}
Run Code Online (Sandbox Code Playgroud)
上面的函数首先插入一个新的shared_ptr,然后将值从一个对象分配到另一个对象,
我的答案就是要告诉我们将临时的shared_ptr插入地图是否安全,并确保它不会是悬空或什么坏事.
根据本网站,上述功能不被认为是安全的,因为写它会更好:
void Table::Field::on_signal_left_top(Drag& drag)
{
std::shared_ptr pointer = std::make_shared<Drag>(this);
m_drag.insert(std::make_pair(drag.id, pointer));
auto iter = m_drag.find(drag.id);
*iter->second = drag;
// etc...
}
Run Code Online (Sandbox Code Playgroud)
在函数中更多一行.
它真的需要这样打字,为什么?
两个函数之间没有区别std::shared_ptr,因为该std::make_pair函数将在临时对象被销毁之前创建临时对象的副本.该副本将被复制到std::map,然后本身将被破坏,留下你在地图中的副本副本.但由于其他两个对象已被破坏,因此地图中对象的引用计数仍为1.
至于处理返回值insert,它很简单:
auto result = m_drag.insert(...);
if (!result.second)
{
std::cerr << "Could not insert value\n";
return;
}
auto iter = result.first;
...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8671 次 |
| 最近记录: |