C++中声明类Node变量时添加struct前缀无报错的原理是什么?
问题解答
你观察到的现象是C的**详细类型说明符(Elaborated Type Specifier)**特性,以及C对C语言向后兼容的设计导致的,具体原理如下:
- C语言要求使用结构体、联合体、枚举类型时,必须在类型名前加
struct/union/enum前缀,除非通过typedef定义别名。C++为了兼容C的旧代码,保留了这一语法,同时扩展了规则:只要是类类型(不管是用class还是struct关键字定义的),引用时添加struct或者class前缀都是合法的。 - 你的代码中已经提前用
class关键字定义了Node类类型,编译器解析到struct Node *newNode时,会匹配到已存在的Node类型,不会认为你要新定义一个结构体类型,因此不会报错,struct Node和直接写Node在这个场景下完全等价。
注意事项
- 该规则有一个前提:当前作用域内已经声明了对应名称的类类型。如果在
Node类型声明前就写了struct Node *newNode,编译器会将其视为struct Node的前向声明,后续再用class定义Node时会出现类型不匹配的编译错误,示例如下:
struct Node *p; // 前向声明为struct类型的Node class Node {}; // 编译报错:Node的类型关键字不匹配
- 该特性还可以解决名字隐藏问题:如果当前作用域内有同名变量覆盖了类型名,可以用带
struct/class前缀的详细类型说明符明确指定到类类型:
class Node {}; int Node = 5; // 同名变量隐藏了Node类型 Node obj; // 编译报错,此时Node指向int变量 class Node obj; // 编译正常,明确指定为类类型Node
相关代码(还原后)
class Node { public: int value; Node *next; }; class LinkedList { private: Node *head; public: LinkedList(void) { head = NULL; } ~LinkedList(void){}; void insertAtHead(int); void insertAtLocation(int, int); void Delete(int); void displayList(); int countList(); }; void LinkedList::insertAtHead(int new_value) { struct Node *newNode, *NodePtr = head; newNode = new Node; newNode->value = new_value; newNode->next = NULL; if (!head) head = newNode; else { newNode->next = NodePtr; head = newNode; } cout << "Node successfully inserted at the head\n\n"; }
内容的提问来源于stack exchange,提问作者Daniyal Irfan
相关产品推荐
相关产品推荐

