c++ - 将临时 std::shared_ptr 插入到 std::map 中,这不好吗?

标签 c++ c++11

我正在为我的应用程序设计一个类,它实现了很多标准共享指针和标准容器的使用,例如 std::mapstd::vector

这个问题非常具体所以我只是复制了一段代码 为了澄清起见,从我的标题中.. 这是 header 中声明的快照:

struct Drag;
std::map<short, std::shared_ptr<Drag>> m_drag;
typedef sigc::signal<void, Drag&> signal_bet;
inline signal_bet signal_right_top();

这里是使用上述声明和临时 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();
}

上述函数首先插入一个新的shared_ptr,然后将一个对象的值赋给另一个对象,

我需要从您的回答中判断将临时 shared_ptr 插入 map 是否安全,并确保它不会悬空或任何坏事。

根据 THIS网站上面的函数被认为是不安全的,因为这样写会更好:

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...
 }

函数中多了一行。

真的需要这样输入吗?为什么?

最佳答案

这两个函数在 std::shared_ptr 方面没有区别,因为 std::make_pair 函数会在临时对象被破坏。该拷贝将依次复制到 std::map 中,然后自身将被销毁,在 map 中留下一个拷贝的拷贝。但是因为另外两个对象已经被销毁了,所以对象在map中的引用计数还是1。


至于处理insert的返回值,很简单:

auto result = m_drag.insert(...);
if (!result.second)
{
    std::cerr << "Could not insert value\n";
    return;
}

auto iter = result.first;

...

关于c++ - 将临时 std::shared_ptr 插入到 std::map 中,这不好吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24928084/

相关文章:

c++ - C++ 社区是否就何时应使用异常达成普遍共识?

c++ - 错误 C2440 : 'return' : cannot convert. 适用于 vs140,141 但不适用于 vs142

c++ - QML 访问不可调用函数

C++11 - typeid 唯一性

c++ - 如何为许多短任务设计线程

c++ - 具有返回抽象类型的函数头是否合法?

c++ - 通过可变参数模板进行通用聚合初始化

c++ - 如何让 lambda 成为类(class)的 friend ?

c++ - 无法将参数 1 从 'const boost::shared_mutex' 转换为 'const boost::shared_lock<Mutex> &'

c++ - Efficient Ransac 的模板化内核存在问题