C++ 为什么当我传递类指针时调用析构函数
C++ Why is Destructor called when I pass a Class Pointer?
int main(){
//Node is some template class
Node<int>* head = new Node<int>[5];
for(int ii = 0; ii < 5; ii++)
{
head[ii].set_Data(ii);
head[ii].set_Link(head + (ii + 1));
if(ii == 4)
{
head[ii].set_Link(NULL);
}
}
delete [] head;
}
template<typename T>
void Node<T>::set_Link(Node* Node_Address)
{
Link = Node_Address;
}
template<typename T>
Node<T>::~Node()
{
delete Link;
cout << "Destructor" << endl;
}
我现在正在学习链表。我不明白为什么我的析构函数被调用 15 次,cout 语句被打印 15 次。如果我摆脱了声明
head[ii].set_Link(head + (ii + 1));
析构函数只被调用 5 次,这是有道理的,因为创建了 5 个类。为什么当我使用成员函数 set_Link(( 时调用析构函数,当我只传递指针而不是类时。甚至没有调用复制构造函数。感谢您的任何帮助!
这里有 UB。析构函数被多次调用。 delete [] head;
调用数组中每个对象的析构函数。析构函数又通过 delete Link;
调用链接对象的析构函数。
在总共析构函数中称为 5 + 4 + 3 + 2 + 1 = 15 次。主要是在已经摧毁的物体上。
通常,您不会为链表的元素创建数组。相反,请像这样创建列表:
Node<int>* head = new Node<int>();
Node<int>* node = head;
for(int ii = 0; ii < 5; ii++)
{
node->set_Data(ii);
if(ii == 4)
{
node.set_Link(NULL);
}
else
{
Node<int>* next = new Node<int>();
node->set_Link(next);
node = next;
}
}
delete head;
在链表节点析构函数中,您不想删除指向的下一个节点。这将级联删除所有尾节点。您可以通过先将指针设置为 NULL 来防止它,但这只是一个可维护性的噩梦,它会产生很多像这样的微妙错误。
注意:"为什么当我使用成员函数 set_Link((" 时调用析构函数" - 它不会被调用,并且通过添加一些额外的跟踪消息来验证这一点非常容易。所有析构函数调用都源自该delete []
调用。
五个节点的完整数组是通过 new 创建的,没关系。但是你传递给set_Link()
的指针指向这个内存块中的某个地方,所以(a(当你的析构函数调用delete Link;
时,堆管理器不知道如何处理它们,(b(即使它知道,它们也会被多次删除,因为你的五个对象会互相删除。
请注意:您只需要delete
通过new
获得的东西
相关文章:
- 为什么使用 "this" 指针调用派生成员函数?
- 当使用通配符和null指针调用函数时,对输出的说明
- Visual c ++,使用字符串引用/指针调用 dll 函数
- 使用基类指针调用基类的值构造函数的语法是什么?
- 是否可以使用函数指针调用虚拟析构函数?
- 使用C++指针调用 python 函数
- 如何使用接口指针调用方法,该指针是其具体类的一部分,而不是接口的一部分
- 是否可以使用非常量指针调用非常量函数,以及当两个unique_ptrs指向同一个对象时程序的行为方式?
- 在将派生类指针类型转换为派生类指针后,从基类指针调用派生类函数
- 通过指针调用模板类成员函数 [为什么这是有效的 c++]?
- 从带有参数的基函数指针调用基方法
- 使用唯一指针调用函数会使我的程序崩溃
- C++::在构造函数退出之前通过指针调用成员函数
- 有没有办法在没有虚拟的情况下使用基类指针调用派生类函数
- 什么时候用指针调用C++类构造函数
- C++ - 使用变量指针调用函数
- 为什么我可以通过野生指针调用成员函数
- 从指针调用方法时出现分段错误
- 为什么使用指向函数的指针调用虚函数时不需要指针"this"?
- C++ abort() 在函数内的抽象类对象指针调用上