将 std::unique_ptr 传递给 CListBox::GetSelItems

Posted

技术标签:

【中文标题】将 std::unique_ptr 传递给 CListBox::GetSelItems【英文标题】:Passing a std::unique_ptr to CListBox::GetSelItems 【发布时间】:2021-10-21 08:12:49 【问题描述】:

我在这里看到了一个很好的答案,这在很大程度上帮助了我 (Proper way to create unique_ptr that holds an allocated array),但我仍然有一个问题。

代码:

void CSelectedBroHighlight::BuildSelectedArray()

    CString     strText;
    
    // empty current array
    m_aryStrSelectedBro.RemoveAll();
    
    // get selected count
    const auto iSize = m_lbBrothers.GetSelCount();
    if(iSize > 0)
    
        //auto pIndex = std::make_unique<int[]>(iSize);

        auto pIndex = new int[iSize];
        m_lbBrothers.GetSelItems(iSize, pIndex);
        
        for(auto i = 0; i < iSize; i++)
        
            m_lbBrothers.GetText(pIndex[i], strText);
            m_aryStrSelectedBro.Add(strText);
        
        
        delete[] pIndex;
    

如果我把pIndex 变成智能指针:

auto pIndex = std::make_unique<int[]>(iSize);

这样我就不需要delete[] pIndex; 电话。然后我不能将pIndex 传递给GetSelItems。我可以在这里传递pIndex.release(),但是我们又遇到了删除问题。

我已查看此讨论 (Issue passing std::unique_ptr's),但我们不想传递所有权。 如果我简化它并声明我的变量:auto pIndex = std::make_unique&lt;int[]&gt;(iSize).release();,那么我可以传递它,但现在调用delete[] pIndex; 时遇到问题。

什么是正确的?

【问题讨论】:

【参考方案1】:

如果您需要在不转移所有权的情况下访问指向由std::unique_ptr 管理的对象的指针,您可以调用其get() 方法。这对于与诸如此处的 C 接口的互操作很有用(GetSelItems() 实际上只是用LB_GETSELITEMS 消息包装对SendMessage 的调用)。

这可行,但在这种情况下,我可能会改用std::vector&lt;int&gt;。它在自动清理方面提供与std::unique_ptr 相同的属性,但还具有其他派上用场的功能(特别是范围适配器)。在这里使用容器也感觉更自然,但这是个人喜好问题。

以下实现了建议的更改:

void CSelectedBroHighlight::BuildSelectedArray() 
    // empty current array
    m_aryStrSelectedBro.RemoveAll();
    
    // get selected count
    auto const sel_item_count m_lbBrothers.GetSelCount() ;
    if(sel_item_count > 0) 
        // get selected indices
        std::vector<int> sel_items(sel_item_count);
        m_lbBrothers.GetSelItems(sel_items.size(), sel_items.data());
        
        // iterate over all selected item indices
        for(auto const index : sel_items) 
            CString strText;
            m_lbBrothers.GetText(index, strText);
            m_aryStrSelectedBro.Add(strText);
        
    

这提供了与基于 std::unique_ptr 的实现相同的自动清理功能,但还允许使用基于范围的 for 循环进一步向下。

【讨论】:

感谢您使用std::vector 的解释和示例,这确实似乎是最好的!

以上是关于将 std::unique_ptr 传递给 CListBox::GetSelItems的主要内容,如果未能解决你的问题,请参考以下文章

std::list< std::unique_ptr<T> >:传递它

通过变量传递 unique_ptr [重复]

unique_ptr 并传递给连接

通过rvalue传递不会破坏对象

智能指针unique_ptr记录

工厂:如何将临时智能指针传递给函数。 C++