C:在函数内创建新对象并将其作为结果返回时,我是否必须使用new
我有两个虚拟的问题让我困惑了一段时间.我确实做了一些在线搜索并阅读了很多c教程,但是我找不到具体的答案.
假设我们有一个名为Node的类,它是单链表的构建块. class Node { int data; Node* next; } 事实1:局部变量(非静态)将在相应函数退出时被销毁. 问题1:情况如何打击: Node* func() { Node n; Node* ptr=&n; return n; } 节点n会被破坏吗?或者我们必须使用new运算符来创建节点并返回指向堆内存的指针.如果两种方式都有效,哪种方法更好? 问题2:如何为节点类编写析构函数? (我在stackOverflow上找到了一些类似的问题,但那些答案集中在链表的析构函数上.我已经得到了那个部分.我想要的只是Node类的析构函数). —————————————感谢大家!我知道了 – – – – – – – – – – – – – – – – – – 感谢所有给我建议或指出我的错误的人.我想我得到了答案.以下是我从你的答案中得到的一个注释,这真的打败了我的困惑. >从函数返回堆栈内存地址不是一个好习惯,因为它会导致未定义的行为. 解决方法
问题1
Node* func() { Node n; Node* ptr=&n; return n;} 您的代码创建一个本地Node实例(在堆栈上),然后返回其地址.当函数返回时,作为局部变量的Node实例将被销毁.函数返回的地址现在指向具有未定义内容的某些内存,并且任何取消引用此指针的尝试都将导致未定义的行为. 为了创建节点,您实际上需要调用Node构造函数.如何返回结果与调用构造函数的方式有关. >您可以按照尝试返回指针,在这种情况下,您需要使用new运算符: Node* func() { Node* pn = new Node(10); return n; } 但是,当您执行此操作时,您将为func调用方提供销毁相关对象的责任.由于new和delete是对称操作,因此将它们放在代码中的对称位置被认为是更好的形式,例如像这样: void cnuf(Node* p) { delete p; } 一个更好的替代方案可能是使用std :: shared_ptr,它为您提供引用计数,如下所示: std::shared_ptr<Node> func() { return std::make_shared<Node>(10); } 使用此方法,调用者无需手动管理每个节点的生命周期.另一种方法是使用std :: unique_ptr,它只允许单个对象所有权. Node func() { Node n(10); return n; } 问题2 您可以在Node类声明中声明这样的析构函数: class Node { ... ~Node(); } 然后,您可以像这样定义它: Node::~Node() { ... } 但是,实际上让列表管理其Node实例(下一个字段)之间的连接,并且只让Node类管理其成员数据的生命周期(数据字段)可能更好. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |