2

我在这里看到了一个很好的答案,这在很大程度上帮助了我(创建包含分配数组的 unique_ptr 的正确方法)但我仍然有一个问题。

代码:

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()这里,但是我们再次删除时遇到了问题。

  • 我看过这个讨论(问题传递 std::unique_ptr's),但我们不想传递所有权。
  • 如果我简化它并声明我的变量:auto pIndex = std::make_unique<int[]>(iSize).release();那么我可以传递它,但现在有调用delete[] pIndex;.

什么是正确的?

4

1 回答 1

3

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

那行得通,尽管在这种情况下,我可能会改用 a std::vector<int>。它在自动清理方面提供了与 a 相同的属性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循环。

于 2021-10-21T09:28:13.497 回答