创建新对象时使用 `new classObject` 和 `&classObject` 有什么区别?

What is the difference between using `new classObject` and `&classObject` when creating a new object?

下面是我的代码,其中我定义了两个 类 NodeList 来做你认为他们做的事情。在扩展列表时,我需要创建一个新的 Node 对象(请参阅 我的代码中带有注释的行 )。如果我使用 new Node(data) 那么一切似乎都很好,输出是

2 3 5

但是如果我把它改成&Node(data),输出就变成了

7530648 7530648 7530648 7530648 7530648 7530648 7530648 7530648 7530648 7530648 7530648 7530648
7530648 7530648 7530648 7530648 7530648 7530648 7530648 7530648 7530648 7530648 7530648 7530648

(依此类推;除非我关闭 window,否则不会结束)

这里使用new Node(data)&Node(data)有什么区别?为什么第二种情况的输出这么奇怪?

请注意,我为我的 TDM-GCC-64-5.1.0 编译器使用了 -fpermissive 选项。虽然这似乎是一个糟糕的选择,但我刚刚意识到我是什么实际上不确定的是由表达式 Node(data) 创建的 Node 对象存在多长时间。所以希望这个问题对那些可能有同样困惑的人仍然有用。

#include<iostream>
using namespace std;

class Node
{
    int _data;
    Node* _next;
public:
    Node(int data) { _data = data; _next = 0; }
    void setNext(Node* next) { _next = next; }
    Node* getNext() const { return _next; }
    int getData() const { return _data; }
};

class List
{
    Node* _head;
public:
    List() { _head = 0; }
    void add(int data)
    {
        if(!_head)
        {
            _head = new Node(data);
            return;
        }
        Node* temp = _head;
        while(temp->getNext())
            temp = temp->getNext();
        temp->setNext(new Node(data)); // What if I use `&Node(data)` instead of `new Node(data)`?
    }
    void print() const
    {
        Node* temp = _head;
        while(temp)
        {
            cout<<temp->getData()<<" ";
            temp = temp->getNext();
        }
    }
};


int main()
{
    List L;
    L.add(2);
    L.add(3);
    L.add(5);
    L.print();
}

What is the difference between using new classObject and &classObject

new classObject 创建具有动态存储的 classObject 类型的新对象。

&classObject returns标识符命名的对象的地址classObject.

&Node(data)

这个表达式的格式不正确。 addressof 运算符的操作数在这里是一个右值。那是不允许的。成功编译程序不需要编译器,标准也没有描述程序应该如何运行。以下是随机选择的编译器的示例输出:

error: taking the address of a temporary object of type 'Node' [-Waddress-of-temporary]
        temp->setNext(&Node(data));
                      ^~~~~~~~~~~

但是一些编译器允许将其作为语言扩展。在这种情况下,这会创建一个 Node 类型的临时对象。临时的生命周期持续到完整表达式结束。 addressof 运算符应用于临时对象,结果是指向临时对象的指针。完整表达式后,指针值将无效。

尝试通过无效指针访问其生命周期之外的临时文件将出现未定义的行为。

Why is the output of the second case so weird?

因为程序的行为是未定义的。


Node* _next;
void setNext(const Node* next) { _next = next; }

指向 const 的指针不能隐式转换为指向非常量的指针。这也是病态的。以下是随机选择的编译器的示例输出:

error: assigning to 'Node *' from incompatible type 'const Node *'
    void setNext(const Node* next) { _next = next; }
                                             ^~~~

new Node(data)&Node(data) 相似 观点,因为它们都是指向 Node.
的指针 在第一种情况下,这个 Node 是动态分配的,应该 有一天或另一天明确 deleted。
在第二种情况下,您使用临时 Node 的地址 (&) 在不久的将来会自动消失;这将导致 使用悬挂指针(一个体面的编译器应该防止 犯了这个错误)。
那么在第二种情况下,您的算法使用了无效数据;就这样 奇怪的显示。
(所有这些临时节点似乎都位于 内存 - 一个接一个 - 然后你的算法无限循环 在同一个)