单链表类中指向类自身的指针问题

2025-03-10 04:17:52
推荐回答(2个)
回答1:

注意了,此处定义的是一个类(数据类型),并没有看到实际的对象(类实例,变量)。Node类的某一对象含一个指向Node类对象的指针next,next可以指向自己,也可以指向其他Node类对象。您不能说next包含什么,只能说next指向的对象包含什么,而next仅仅是一个指针,除了指向自己、别的Node对象以外,还可以是NULL。
举例说明,Node A,B;Node *pn=&B;调用A的成员函数A.InsertAfter(pn)时,将next即this->next即A.next复制给pn->next即B.next,A的后继成为B的后继;由把pn即&B复制给next即this->next即A.next,B成为A的后继:如此实现在A和其后继之间插入结点B。
关于this指针的问题,假设您不懂的话(您已经理解则最好),我在此简单说明一下,您最好此外系统学习一下:调用类对象的成员函数时,系统后台有一this指向该对象,该成员函数中引用的该类的成员函数或成员变量,如果不加以限定都认为是属于this指向的该对象的。

回答2:

你的问题很经典,主要的对指针,类的实例化等等理解还不是很深刻。
在回答这个问题之前,简单回顾下指针。
a) 指针是占 4 字节(32位机器上)的一种数据,主要是用来存放某个具体数据的地址。
b) 再重复一次,指针式要占据内存的,只不过是4字节。这个内存不是其指向的内存。
比如说,char* p; char* buf[256]; p = buf; p 自己要花费 4 个存储空间, p 指向的地方也要花费 256 个存储空间。 理解这点上很重要的。

实例化
简单说说什么是实例化。在这里,你就理解为一个对象的具体化,比如说“人”是一个类,但我们说“张三”,这就是一个具体的对象,就是人这个对象的一次实例化,是需要花费计算机存储空间的。每个现实的实例都是需要内存表达的。(不然张三是如何存在的呢?)

回到你的问题,在回答具体问题前,还是先扩充点与之有关的东西。
a ) sizeof(Node) = ? .... 8 自己想想为什么是 8 ? 还是告诉你吧, Node* 4 字节, data 4 字节。
b) 每实例化一次 Node 系统就好开销 8 个存储单元。

回答你的具体的问题
问题1. 结合我上面说的,区分指针和指针指向的对象,就能解决自己的疑惑。
Next 是指针,不包含 data 成员,next 指向的对象包含 data。 next 指向自己是可以的,在代码上, next->data 与 data, this->data 都是访问同一块内存。

问题2:
void Node::InsertAfter(Node *p)
{
p->next=next; // 这个可是删除当前节点
next=p; // ???
}
这个段代码的含义有点混乱。(我也不知道你想干嘛!)
如果想在某个节点后面插入自己,则代码修改如下。
void Node::InsertAfter(Node *p)
{
Node* pTemp = p->next; // p 原来后面的节点
p->next = this; // 把当前节点设置为 p 的新的下一个节点
next = pTemp; // 把 P 原来后面的节点,放到当前节点后面
}