删除动态创建的组件?
Deleting dynamically created component?
在 OnCreate
事件中,我有将菜单项添加到 std::vector
的代码(出于这个问题的目的,它可以是按钮,或者我们使用动态创建的任何其他组件new
运算符):
// Iterrate through styles and hints and construct menu
for (int i=0; i<styleNamesAndHints->Count; i++) {
TMenuItem* miTheme = new TMenuItem(miRoot);
miTheme->Caption = styleNamesAndHints->Strings[i].SubString(0, styleNamesAndHints->Strings[i].Pos(styleNamesAndHints_Delimeter)-1);
miTheme->AutoCheck = false;
miTheme->AutoHotkeys = maManual;
miTheme->RadioItem = false;
miTheme->GroupIndex = MENU_GROUP_INDEX_STYLES;
miTheme->OnClick = &miStyles_Click;
miTheme->OnDrawItem = &miStyles_DrawItem;
miTheme->OnMeasureItem = &miStyles_MeasureItem;
miTheme->ImageIndex = IL_MENU_A_THEME;
miTheme->Tag = miStyleArray.size();
miStyleArray.push_back(miTheme);
miRoot->Add(miTheme);
}
然后在OnDestroy
事件中,我们清理向量miStyleArray
:
// Clean up miStyleArray vector, delete each element
while(miStyleArray.empty()==false) {
delete miStyleArray.back();
miStyleArray.pop_back();
}
此代码有效...我没有错误,一切正常....
现在,有人告诉我这样的代码可能会导致错误,我引用,我不应该在具有父对象的对象上使用运算符 delete
,对象的父对象负责销毁和清理向上..
事实上,告诉我这个的人是C++Builder论坛的版主,并警告我下次可能会因为这样的代码而被禁止!这里是 post link.
谁对谁错??
手动 delete
分配了 Owner
或 Parent
的组件实例是完全安全的。组件的析构函数将从其 Owner
/Parent
的内部列表中删除该实例,因此该实例不会被第二次释放。
另一方面,分配了 Owner
的组件实例不需要手动 delete
,它会在其 Owner
被释放时被释放,所以您的 OnDestroy
代码是多余的,可以删除。
附带说明:您不应 在 C++Builder 中使用表单的 OnCreate
和 OnDestroy
事件。它们是一个 Delphi 习语,如果您不小心,可以 导致 C++ 中的 未定义行为。 OnCreate
可以 在窗体的构造函数之前触发,而 OnDestroy
可以 在窗体的析构函数之后触发。因此,您应该改用窗体的实际构造函数和析构函数。
在 OnCreate
事件中,我有将菜单项添加到 std::vector
的代码(出于这个问题的目的,它可以是按钮,或者我们使用动态创建的任何其他组件new
运算符):
// Iterrate through styles and hints and construct menu
for (int i=0; i<styleNamesAndHints->Count; i++) {
TMenuItem* miTheme = new TMenuItem(miRoot);
miTheme->Caption = styleNamesAndHints->Strings[i].SubString(0, styleNamesAndHints->Strings[i].Pos(styleNamesAndHints_Delimeter)-1);
miTheme->AutoCheck = false;
miTheme->AutoHotkeys = maManual;
miTheme->RadioItem = false;
miTheme->GroupIndex = MENU_GROUP_INDEX_STYLES;
miTheme->OnClick = &miStyles_Click;
miTheme->OnDrawItem = &miStyles_DrawItem;
miTheme->OnMeasureItem = &miStyles_MeasureItem;
miTheme->ImageIndex = IL_MENU_A_THEME;
miTheme->Tag = miStyleArray.size();
miStyleArray.push_back(miTheme);
miRoot->Add(miTheme);
}
然后在OnDestroy
事件中,我们清理向量miStyleArray
:
// Clean up miStyleArray vector, delete each element
while(miStyleArray.empty()==false) {
delete miStyleArray.back();
miStyleArray.pop_back();
}
此代码有效...我没有错误,一切正常....
现在,有人告诉我这样的代码可能会导致错误,我引用,我不应该在具有父对象的对象上使用运算符 delete
,对象的父对象负责销毁和清理向上..
事实上,告诉我这个的人是C++Builder论坛的版主,并警告我下次可能会因为这样的代码而被禁止!这里是 post link.
谁对谁错??
手动 delete
分配了 Owner
或 Parent
的组件实例是完全安全的。组件的析构函数将从其 Owner
/Parent
的内部列表中删除该实例,因此该实例不会被第二次释放。
另一方面,分配了 Owner
的组件实例不需要手动 delete
,它会在其 Owner
被释放时被释放,所以您的 OnDestroy
代码是多余的,可以删除。
附带说明:您不应 在 C++Builder 中使用表单的 OnCreate
和 OnDestroy
事件。它们是一个 Delphi 习语,如果您不小心,可以 导致 C++ 中的 未定义行为。 OnCreate
可以 在窗体的构造函数之前触发,而 OnDestroy
可以 在窗体的析构函数之后触发。因此,您应该改用窗体的实际构造函数和析构函数。