4

假设我有一个我自己创建的链接列表。它有自己的析构函数,可以释放内存。此链接列表不会重载 new 或 delete。

现在,我正在尝试创建一个所述链接列表的数组(如果我理解正确,则打开散列)。然后我在这个开放散列类的构造函数中分配必要的内存。在构造函数中调用的 new 运算符足以正确地为数组分配内存,对吧?我不确定,因为我没有为 Linked List 类重载 new 。

另外,假设我的链接列表数组被称为元素,我可以在析构函数中写“删除 [] 元素”吗?这会为数组中的每个元素调用析构函数并正确释放内存吗?

最后,如果我的两个假设都是正确的(即,我不必重载 new 和 delete 就可以将它们与我的自定义类一起使用),那么重载这些运算符有什么意义呢?

4

3 回答 3

6

嗯你是对的。一个平原

elements = new LinkedList[N];

足以分配它们。然后您可以访问它们

elements[i]->push(....);

并使用您展示的方式在您的析构函数中删除它们:

delete[] elements;

编译器会记住分配了多少元素,并正确调用每个列表的析构函数。重载 new 和 delete 运算符的目的是提供自定义的内存分配策略。例如,您可以预先分配内存,然后从该池中取出,而不是每次都从操作系统分配内存。

但请注意,您还必须编写一个复制构造函数和复制赋值运算符。因为如果有人复制了您的哈希图,那么链表也必须被复制,而不仅仅是指针。或者您可以将复制构造函数和复制赋值运算符设为私有而不定义它们,从而禁止复制哈希映射:

....
private:
    MyHashMap(MyHashMap const& rhs);
    MyHashMap & operator=(MyHashMap const& rhs);
....
于 2008-12-25T02:51:39.707 回答
3

new运算符做了两件事:分配内存和调用构造函数。

删除操作符调用析构函数,然后释放内存。

使用new []创建的数组必须使用delete[]销毁。

除非出于性能原因,您通常不需要重载newdelete 。您可能有一个可预测的分配/解除分配模式,这使得特定的分配策略非常适合(快速或低内存使用)。

你不妨看看这个页面

于 2008-12-25T03:00:23.027 回答
1

你所有的假设都是正确的。

重载 new 和 delete 有很多用途,但并不经常这样做。一个常见的原因是跟踪内存分配以发现内存泄漏。很多编译时泄漏跟踪器都这样做,但是随着 valgrind 等更好的外部应用程序已经过时了。您还可以执行诸如使用池化内存之类的操作。

于 2008-12-25T02:54:07.020 回答