指针和双向链表

Pointers and doubly-linked list

我目前正在阅读 "Programming: Principles and Practice using C++" 的第 17 章,我在双向链表上看到了一段代码。之前有人对这组代码提出过问题(例如 ),但我有一个问题不是 asked/answered.

代码基本上将 "Freya" 安排为 "Odin" 的前导,并使 "Odin" 成为 "Thor" 的前导,反之亦然。代码如下:

struct Link {
string value;
Link* prev;
Link* succ;
Link(const string& v, Link* p = nullptr, Link* s = nullptr)
    : value(v), prev(p), succ(s) {}
};

int main()
{
    Link* norse_gods = new Link{ "Thor", nullptr, nullptr };
    norse_gods =       new Link{ "Odin", nullptr, norse_gods };

    norse_gods->succ->prev = norse_gods;
    norse_gods =       new Link{ "Freya", nullptr, norse_gods };

    norse_gods->succ->prev = norse_gods;

}

我想知道的是为什么代码:

norse_gods =       new Link{ "Odin", nullptr, norse_gods }

能够指向旧地址:new Link{ "Thor", nullptr, nullptr },并使 Thor 成为 Odin 的继任者,因为 norse_god 应该已经指向新地址:new Link{ "Odin", nullptr, norse_gods }?有没有我遗漏的顺序、评估或概念?

首先计算右侧的表达式。这将评估采用 norse_gods 的旧值。一旦这个评估完成,赋值就完成了,新创建对象的引用被赋值给norse_gods.

评估首先在右侧完成,然后 operator= 开始并进行分配。这是operator=的优先级造成的。参见 C++ Operator Precedence

main 的第一行,您正在创建名称为 "Thor" 的 Link 并将 norse_gods 指向它。

在第二行,您正在创建一个名为 "Odin" 的 Link 和一个后继者 norse_god,在构建时它仍然指向 Thor。

之后,norse_gods 更新为指向 "Odin"。

这种行为对于类 C 语言是正常的。