我有一个abstract
Base
班级和Derived
班级。
int main ()
{
Base *arrayPtr[3];
for (int i = 0; i < 3; i++)
{
arrayPtr[i] = new Derived();
}
//some functions here
delete[] arrayPtr;
return 0;
}
我不确定如何使用delete运算符。如果我删除了如上所示的基类指针数组,那么这会调用派生类对象的析构函数并清理内存吗?
答案 0 :(得分:10)
不,您必须明确删除数组中的每个项目:
for (int i = 0; i < 3; ++i)
{
delete arrayPtr[i];
}
答案 1 :(得分:10)
您必须迭代数组的元素delete
。 如果数组已使用delete []
动态分配,请在数组上调用new[]
。
在示例代码中,数组已在堆栈上分配,因此您不能在其上调用delete []
。
还要确保您的Base
班级有virtual
析构函数。
答案 2 :(得分:2)
你应该这样做:
for ( int = i; i < 3; i++ )
{
delete arrayPtr[i];
}
当你试图释放/删除分配了delete[] arrayPtr;
的堆栈时,你不应该arrayPtr
。
要考虑的另一件事是使用std::vector
指针而不是数组。如果您使用的是实现TR1的编译器,您也可以使用std::vector
std::tr1::shared_ptr
而不是原始指针,而不必担心自己删除这些对象。
示例:
{
std::vector< std::tr1::shared_ptr<Base> > objects;
for (int i=0; i < 3; ++i)
{
objects.push_back(std::tr1::shared_ptr<Base>(new Derived()));
}
} // here, once "objects" exit scope, all of your Derived objects are nicely deleted
答案 3 :(得分:1)
您必须单独删除阵列的成员。您还必须确保您的基类具有虚拟析构函数。您可能还想考虑将其设置为智能指针的数组(或更好的std :: vector),例如boost :: shared_ptr。
答案 4 :(得分:1)
不,你不能这样做。正如其他人建议您必须浏览每个项目并将其删除。记住这是一个非常简单的规则。如果您使用new
分配,则使用delete
,如果您使用了new[]
,则使用delete[]
答案 5 :(得分:1)
注意缺席的是什么:
int main() {
boost::ptr_vector<Base> v;
for (int i = 0; i < 3; i++) v.push_back(new Derived());
// some functions here, using v[0] through v[2]
}
答案 6 :(得分:1)
操作员删除必须与该指针上的operator new匹配,如果它已分配new[]
,则必须调用delete[]
,反之亦然;
int* pInt = new int;
delete pInt; OK
delete [] pInt; WRONG
int[] pIntArr = new int[3];
delete [] pIntArr; OK
delete pIntArr; WRONG
在你的情况下还有其他错误 - 你正在尝试在堆栈上分配的delete
。那不行。
在这种特殊情况下,您必须单独删除每个指针。
答案 7 :(得分:1)
你有什么未定义的行为 - 一个错误。每次拨打new
都需要与delete
匹配;每次拨打new[]
都需要与delete[]
匹配。两者是分开的,不能混合。
在您发布的代码中,您有一个指向堆栈上Base的指针数组。然后你在堆栈上分配的数组上调用delete[]
- 你不能这样做。您只能delete[]
使用new[]
在堆上分配的数组。
对于使用delete
分配的每个元素,您需要调用new
- 或者最好使用容器类(例如std::vector
)而不是使用数组。
答案 8 :(得分:0)
确保Base
有一个虚拟析构函数。然后像fretje outlined一样删除数组中的每个元素,然后删除数组。
您应该使用std::vector
作为数组。也就是说,你应该真的使用为这类东西制作的容器。 (所以你不会意外地删除所有元素,如果抛出异常肯定会出现这种情况!)Boost有such a library。
答案 9 :(得分:0)
不,这不是你想要的。
这里有两点需要注意:
如果动态分配数组,则使用语法delete[] arrayPtr
,如下所示:
arrayPtr = new (Base *)[mylength];
但是,在您的情况下,您有一个静态分配的数组,因此无需删除它。但是,您需要删除数组中的各个元素:
for ( int = i; i < 3; i++ )
delete arrayPtr[i];
您需要注意的第二点是使类Base
的析构函数为虚拟:
class Base
{
virtual ~Base();
/* ... */
};
这可确保当您在Base *
上调用实际指向Derived
的删除时,会调用Derived
的析构函数,而不仅仅是Base
的析构函数
答案 10 :(得分:0)
您正在混合范例 - 数组删除运算符旨在释放由数组new运算符分配的内存,但您将堆栈上的数组作为指针数组分配,然后为每个数组成员分配一个对象。在您的代码中,您需要遍历数组。
要使用数组new运算符,您将声明如下:
Base *array;
array = new Base[3];
/* do stuff */
delete[] array;
这为三个对象分配了一个连续的内存区域 - 请注意,你有一个Base对象数组,而不是一个指向Base对象的数组。