【C++系列】指针对象和对象指针的区别

简介: 这段内容介绍了C++中`ListNode`对象和指针的两种使用方式以及它们的区别。首先,`ListNode dummy(0); ListNode* cur = &dummy;创建了一个`ListNode`对象`dummy`在栈上,`cur`是`dummy`的地址。而`ListNode* dummy = new ListNode(0); ListNode* cur = dummy;`则在堆上分配了一个`ListNode`,`dummy`和`cur`都是指向该对象的指针。使用`&dummy`作为虚拟头节点简化链表操作,避免特殊处理。栈分配内存自动管理但生命周期受限,堆分配内存需手动释放且速度较慢。

ListNode dummy(0);ListNode* cur = &dummy; 中,& 是取地址运算符,用来获取变量 dummy 的地址。具体如下:

  • ListNode dummy(0);:创建了一个类型为 ListNode 的对象 dummy,其值初始化为 0
  • &dummy:取 dummy 对象的地址。& 运算符用于获取变量的内存地址。
  • ListNode* cur = &dummy;:声明了一个指向 ListNode 类型的指针 cur,并将其初始化为指向 dummy 的地址。

ListNode* dummy = new ListNode(0); ListNode* cur = dummy; 中,dummy 是链表指针。具体如下:

  • ListNode* dummy = new ListNode(0);:创建了一个类型为 ListNode* 的链表指针dummy,其值初始化为 ListNode(0)
  • new ListNode(0):实例化一个ListNode(0) 对象。
  • ListNode* cur = dummy;:声明了一个 ListNode 类型的指针 cur,并将其初始化为 dummy 指针。

为什么使用 &dummy

使用 &dummy 主要是为了简化链表的操作。具体来说:

  1. 简化链表操作
  • dummy 是一个虚拟头节点,它的存在使得我们不必处理链表头部的特殊情况(比如在空链表上插入第一个节点,或者在链表头部插入新节点)。
  • 通过使用 dummy,所有插入操作都可以统一处理,不需要额外的条件判断。
  1. 指针操作
  • cur 是一个指针,用于遍历和构建新链表。
  • cur 初始化为 dummy 的地址,这样在向链表中添加第一个节点时,dummy.next 可以直接指向新节点,并且后续操作都可以通过更新 cur 来进行。

区别

  1. 内存分配方式
  • ListNode dummy(0); 是在栈上分配的内存。栈上的内存会在超出作用域时自动释放。
  • ListNode* dummy = new ListNode(0); 是在堆上分配的内存。堆上的内存不会自动释放,需要手动调用 delete 来释放,防止内存泄漏。
  1. 指针的使用
  • ListNode dummy(0); ListNode* cur = &dummy; 这里 dummy 是一个对象,cur 是指向 dummy 的指针。
  • ListNode* dummy = new ListNode(0); ListNode* cur = dummy; 这里 dummy 本身就是一个指针,指向堆上的 ListNode 对象,cur 也指向同一个对象。

优缺点

在栈上分配内存

优点

  • 自动管理内存:函数退出时,栈上的内存会自动释放,无需手动管理。
  • 更快的内存分配和释放:栈上的内存操作通常比堆上的快。

缺点

  • 生命周期受限:栈上的对象在函数返回后就被释放,不适合需要在函数外部长期使用的对象。

在堆上分配内存

优点

  • 生命周期灵活:可以手动控制对象的生命周期,适合需要在函数外部长期使用的对象。

缺点

  • 手动管理内存:需要手动释放内存,否则会导致内存泄漏。
  • 相对较慢的内存分配和释放:堆上的内存操作通常比栈上的慢。

在 C++ 中,.-> 操作符用于访问对象的成员:

  • . 操作符用于直接访问对象的成员。
  • -> 操作符用于通过指针访问对象的成员。

区别

  • dummy.nextdummy 是一个对象,通过 . 操作符直接访问 dummy 的成员 next
  • dummy->nextdummy 是一个指向对象的指针,通过 -> 操作符访问指针指向的对象的成员 next

具体示例

栈上分配对象

ListNode dummy(0);       // dummy 是一个对象
ListNode* cur = &dummy;  // cur 是指向 dummy 的指针
cur->next = new ListNode(1);  // 通过 cur 指针访问 next 成员
ListNode* head = dummy.next;  // 直接通过对象 dummy 访问 next 成员

在这个例子中:

  • dummy 是一个 ListNode 对象,可以直接使用 dummy.next 访问其成员。
  • cur 是一个指向 dummy 的指针,使用 cur->next 访问 dummy 的成员。

堆上分配对象

ListNode* dummy = new ListNode(0);  // dummy 是一个指向 ListNode 对象的指针
ListNode* cur = dummy;  // cur 和 dummy 都是指向同一对象的指针
cur->next = new ListNode(1);  // 通过 cur 指针访问 next 成员
ListNode* head = dummy->next;  // 通过 dummy 指针访问 next 成员

在这个例子中:

  • dummy 是一个指向 ListNode 对象的指针,需要使用 dummy->next 访问其成员。
  • cur 同样是一个指向 ListNode 对象的指针,使用 cur->next 访问其成员。

总结

在使用栈上分配的对象时,使用 . 操作符访问成员,因为我们直接处理的是对象本身。而在使用堆上分配的对象时,使用 -> 操作符访问成员,因为我们处理的是指向对象的指针。

相关文章
|
6天前
|
存储 编译器 C++
【c++】类和对象(中)(构造函数、析构函数、拷贝构造、赋值重载)
本文深入探讨了C++类的默认成员函数,包括构造函数、析构函数、拷贝构造函数和赋值重载。构造函数用于对象的初始化,析构函数用于对象销毁时的资源清理,拷贝构造函数用于对象的拷贝,赋值重载用于已存在对象的赋值。文章详细介绍了每个函数的特点、使用方法及注意事项,并提供了代码示例。这些默认成员函数确保了资源的正确管理和对象状态的维护。
29 4
|
7天前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
25 4
|
23天前
|
存储 安全 编译器
在 C++中,引用和指针的区别
在C++中,引用和指针都是用于间接访问对象的工具,但它们有显著区别。引用是对象的别名,必须在定义时初始化且不可重新绑定;指针是一个变量,可以指向不同对象,也可为空。引用更安全,指针更灵活。
|
30天前
|
存储 编译器 对象存储
【C++打怪之路Lv5】-- 类和对象(下)
【C++打怪之路Lv5】-- 类和对象(下)
27 4
|
30天前
|
编译器 C语言 C++
【C++打怪之路Lv4】-- 类和对象(中)
【C++打怪之路Lv4】-- 类和对象(中)
23 4
|
30天前
|
存储 C语言
C语言指针与指针变量的区别指针
指针是C语言中的重要概念,用于存储内存地址。指针变量是一种特殊的变量,用于存放其他变量的内存地址,通过指针可以间接访问和修改该变量的值。指针与指针变量的主要区别在于:指针是一个泛指的概念,而指针变量是具体的实现形式。
|
30天前
|
存储 安全 C++
【C++打怪之路Lv8】-- string类
【C++打怪之路Lv8】-- string类
21 1
|
1月前
|
存储 编译器 C++
【C++类和对象(下)】——我与C++的不解之缘(五)
【C++类和对象(下)】——我与C++的不解之缘(五)
|
1月前
|
编译器 C++
【C++类和对象(中)】—— 我与C++的不解之缘(四)
【C++类和对象(中)】—— 我与C++的不解之缘(四)
|
1月前
|
C++
C++番外篇——对于继承中子类与父类对象同时定义其析构顺序的探究
C++番外篇——对于继承中子类与父类对象同时定义其析构顺序的探究
53 1