将 std::unique_ptr 传递给 CListBox::GetSelItems
Passing a std::unique_ptr to CListBox::GetSelItems
我在这里看到了一个很好的答案,这在很大程度上帮助了我 (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<int[]>(iSize).release();
然后我可以传递它,但现在有调用 delete[] pIndex;
. 的问题
什么是正确的?
如果您需要访问指向由 std::unique_ptr
管理的对象的指针而不转移所有权,您可以调用它的 get()
method. This is useful for interop with a C interface such as here (GetSelItems()
is really just wrapping a call to SendMessage
with the LB_GETSELITEMS
消息。
那行得通,但在这种情况下,我可能会改用 std::vector<int>
。它在自动清理方面提供与 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
循环。
我在这里看到了一个很好的答案,这在很大程度上帮助了我 (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<int[]>(iSize).release();
然后我可以传递它,但现在有调用delete[] pIndex;
. 的问题
什么是正确的?
如果您需要访问指向由 std::unique_ptr
管理的对象的指针而不转移所有权,您可以调用它的 get()
method. This is useful for interop with a C interface such as here (GetSelItems()
is really just wrapping a call to SendMessage
with the LB_GETSELITEMS
消息。
那行得通,但在这种情况下,我可能会改用 std::vector<int>
。它在自动清理方面提供与 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
循环。