C++ 关于C+中的构造函数/析构函数和new/delete运算符+;用于自定义对象

C++ 关于C+中的构造函数/析构函数和new/delete运算符+;用于自定义对象,c++,constructor,destructor,new-operator,C++,Constructor,Destructor,New Operator,假设我有一个我自己创建的链表。它有自己的析构函数,可以释放内存。此链表不会重载“新建”或“删除” 现在,我正在尝试创建一个由上述链表组成的数组(如果我理解正确的话,可以使用开放哈希)。然后在这个开放哈希类的构造函数中分配必要的内存。在构造函数中调用的新运算符足以为数组正确分配内存,对吗?我不确定,因为我没有为链表类重载new 另外,假设我的链表数组被称为元素,我可以在析构函数中写“delete[]elements”吗?这会为数组中的每个元素调用析构函数并正确释放内存吗 最后,如果我的两个假设都是

假设我有一个我自己创建的链表。它有自己的析构函数,可以释放内存。此链表不会重载“新建”或“删除”

现在,我正在尝试创建一个由上述链表组成的数组(如果我理解正确的话,可以使用开放哈希)。然后在这个开放哈希类的构造函数中分配必要的内存。在构造函数中调用的新运算符足以为数组正确分配内存,对吗?我不确定,因为我没有为链表类重载new

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


最后,如果我的两个假设都是正确的(即,我不必重载new和delete来将它们用于我的自定义类),那么重载这样的操作符有什么意义呢?

是的,你是对的。平原

elements = new LinkedList[N];
足够分配它们。然后您可以访问它们

elements[i]->push(....);
并在析构函数中使用显示的方式删除它们:

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

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

....
private:
    MyHashMap(MyHashMap const& rhs);
    MyHashMap & operator=(MyHashMap const& rhs);
....

你所有的假设都是正确的


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

new操作符执行两件事:分配内存和调用构造函数

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

使用新建[]创建的数组必须使用删除[]销毁

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


您可能想看看。

一个小细节:大多数对new的调用都不涉及操作系统。通常,只有当堆需要抓取更多虚拟内存页时,操作系统才会介入。如果必须使用新的,请使用
共享\u ptr
唯一\u prt
。两者都是在c++11STL中引入的。共享指针将自动执行删除的簿记。注意:对于由
shared_ptr
调用delete而不是delete[]提供的数组默认deleter,因此使用lambda函数
std::shared_ptr p(新int[10],](int*p){delete[]p;})
std::shared_ptr p(新的int[10],std::default_delete())
或使用unique_ptr提供的助手,该助手调用delete[]
std::unique_ptr p(新int[10],](int*p){delete[]p;})