将智能指针与属性网格控件一起使用的正确方法是什么,这样我就不必使用
new
?
例如:
auto AddSection = [](CMFCPropertyGridCtrl *pGrid, CString strSection) -> CMFCPropertyGridProperty*
{
CMFCPropertyGridProperty* pSection = nullptr;
pSection = new CMFCPropertyGridProperty(strSection);
pGrid->AddProperty(pSection);
return pSection;
};
纠正这个问题的正确方法是什么?
答案就在MFC源码中。
CMFCPropertyGridCtrl
和 CMFCPropertyGridProperty
的代码都包含在文件 afxpropertygridctrl.cpp 中。
CMFCPropertyGridCtrl::AddProperty()
接受 CMFCPropertyGridProperty*
参数并将其添加到属性列表 (m_lstProps
)。这是一个普通的指针,而不是一个智能指针。它还调用受保护的方法SetOwnerList()
,该方法似乎将其绑定到网格控制项。
还有
RemoveAll()
方法,显然是清除列表的。这里重要的是它为每个列表元素调用 delete
。这意味着属性 must 是通过调用 new
创建的。当然,在拨打 delete
之后,您不应该自己打电话给
AddProperty()
。
CMFCPropertyGridCtrl::AddProperty()
的文档在我看来相当混乱(甚至是错误的):在网格控件被销毁之前,不要销毁属性或允许它们超出范围。属性对象在堆中分配,并且指针(由
new
获得)并不智能,因此如果它超出范围,则不会发生任何事情。您可以进行简单的测试,而不是定义和创建派生类,使用析构函数将一些输出发送到日志文件,或调用
CMFCPropertyGridProperty
(您必须在调试模式下运行应用程序才能看到这些) - 这您可以测试您的财产元素是否被正确破坏的方式。