RAD Studio 10.2 (C++):~TControl() 析构函数仅适用于每二次迭代
RAD Studio 10.2 (C++): ~TControl() destructor only works on every second iteration
每当我尝试 运行 某些在 运行 时间创建的子 TPanel 控件(组件)上的 ~TControl();
析构函数时,它只会每 秒析构一次 子面板(例如,参见下面的代码)。
for(int i=0; i < ParentPanel->ControlCount; i++)
{
ParentPanel->Controls[i]->~TControl();
}
如果我 运行 一次又一次 'for' 循环(我不知道为什么),它只会破坏剩余的子 TPanel 控件。
现在,如果我尝试将其编程为 'manually' 破坏我知道我将在 运行 时间创建的所有子控件(假设有 4 个子 TPanel 控件),它给出我遇到了 "List index out of bounds(#)"
错误,其中 #
是我构建并告诉它手动销毁的控件总数的一半。
ParentPanel->Controls[0]->~TControl();
ParentPanel->Controls[1]->~TControl();
ParentPanel->Controls[2]->~TControl();
ParentPanel->Controls[3]->~TControl();
例如以上将导致它显示 "List index out of bounds (2)"
错误。
即使我改用 delete ParentPanel->Controls[0];
方法也会发生同样的事情。
有什么线索吗?非常感谢您的帮助。提前致谢。
正如@Axbor Axrorov 所说,结果是数组的大小随着每个子控件的销毁/删除而减小。
我发现一种方法是在删除子控件时使用递减运算符--
,这样随着'for'循环中整数的增加,它会不断删除数组中的第一个元素,因为它的大小继续减小(请参见下面的代码)。
for(int i=0; i<ParentPanel->ControlCount; i++)
{
if(ParentPanel->Controls[i] != NULL)
{
delete ParentPanel->Controls[i--];
}
}
最好从索引列表中删除项目:
for (int i = ParentPanel->ControlCount - 1; i >= 0; i--)
{
delete ParentPanel->Controls[i];
}
向上计数的问题
此类列表通常会将所有项目 "above"(具有更高索引)向下移动,因此如果 Controls[i] 被删除,现在一个新控件将移至该索引。但紧随其后,索引增加,因此它指向替换已删除项的项之上的项,并且仅删除该项。所以,实际上,只有每隔一个项目被删除。
Initially: [A] B C D E F G H I J i = 0
索引表示为 [ ]
现在你删除并删除了A,所以新的顺序是:
[B] C D E F G H I J i = 0
但是循环会立即递增索引:
B [C] D E F G H I J i++, so i = 1
因此在下一个循环中,C 被删除(这意味着 B 被跳过)。等等等等。这意味着只有第二个元素被删除。
但是如果您从顶部开始,则不会移动任何元素,因此所有内容都会被删除。
调用析构函数
在我看来,直接调用析构函数是一个极其糟糕的主意。而是使用 delete
.
组件
请注意,如果您想删除所有组件,您应该使用 Components
列表和 ComponentCount
。
您需要删除控件而不是调用析构函数。
while(ParentPanel->ControlCount > 0)
delete ParentPanel->Controls[0];
每当我尝试 运行 某些在 运行 时间创建的子 TPanel 控件(组件)上的 ~TControl();
析构函数时,它只会每 秒析构一次 子面板(例如,参见下面的代码)。
for(int i=0; i < ParentPanel->ControlCount; i++)
{
ParentPanel->Controls[i]->~TControl();
}
如果我 运行 一次又一次 'for' 循环(我不知道为什么),它只会破坏剩余的子 TPanel 控件。
现在,如果我尝试将其编程为 'manually' 破坏我知道我将在 运行 时间创建的所有子控件(假设有 4 个子 TPanel 控件),它给出我遇到了 "List index out of bounds(#)"
错误,其中 #
是我构建并告诉它手动销毁的控件总数的一半。
ParentPanel->Controls[0]->~TControl();
ParentPanel->Controls[1]->~TControl();
ParentPanel->Controls[2]->~TControl();
ParentPanel->Controls[3]->~TControl();
例如以上将导致它显示 "List index out of bounds (2)"
错误。
即使我改用 delete ParentPanel->Controls[0];
方法也会发生同样的事情。
有什么线索吗?非常感谢您的帮助。提前致谢。
正如@Axbor Axrorov 所说,结果是数组的大小随着每个子控件的销毁/删除而减小。
我发现一种方法是在删除子控件时使用递减运算符--
,这样随着'for'循环中整数的增加,它会不断删除数组中的第一个元素,因为它的大小继续减小(请参见下面的代码)。
for(int i=0; i<ParentPanel->ControlCount; i++)
{
if(ParentPanel->Controls[i] != NULL)
{
delete ParentPanel->Controls[i--];
}
}
最好从索引列表中删除项目:
for (int i = ParentPanel->ControlCount - 1; i >= 0; i--)
{
delete ParentPanel->Controls[i];
}
向上计数的问题
此类列表通常会将所有项目 "above"(具有更高索引)向下移动,因此如果 Controls[i] 被删除,现在一个新控件将移至该索引。但紧随其后,索引增加,因此它指向替换已删除项的项之上的项,并且仅删除该项。所以,实际上,只有每隔一个项目被删除。
Initially: [A] B C D E F G H I J i = 0
索引表示为 [ ]
现在你删除并删除了A,所以新的顺序是:
[B] C D E F G H I J i = 0
但是循环会立即递增索引:
B [C] D E F G H I J i++, so i = 1
因此在下一个循环中,C 被删除(这意味着 B 被跳过)。等等等等。这意味着只有第二个元素被删除。
但是如果您从顶部开始,则不会移动任何元素,因此所有内容都会被删除。
调用析构函数
在我看来,直接调用析构函数是一个极其糟糕的主意。而是使用 delete
.
组件
请注意,如果您想删除所有组件,您应该使用 Components
列表和 ComponentCount
。
您需要删除控件而不是调用析构函数。
while(ParentPanel->ControlCount > 0)
delete ParentPanel->Controls[0];