C++ delete ptr 和 ptr = nullptr 的区别

delete ptrdelete ptr 是释放 ptr 所指向的对象资源,而 ptr 依然存在,且依然指向那片内存地址。 ptr = nullptrptr = nullptr 是将 ptr 指向空指针,和其所指向的对象没关系。 试着实现一个 unique_ptrtemplate <typename T> class UniquePtr { private: T *_ptr; public: // 默认构造 UniquePtr() : _ptr(nullptr) { } explicit UniquePtr(T *ptr) : _ptr(ptr) { } ~UniquePtr() { delete _ptr; // 无需置 nullptr,因为析构函数会被调用,_ptr 会被销毁 // 置空无意义 } // 拷贝构造 删除 UniquePtr(const UniquePtr &) = delete; UniquePtr &operator=(const UniquePtr &) = delete; // 移动构造 UniquePtr(UniquePtr &&p) noexcept : _ptr(p._ptr) { // 至于这里为什么不需要 delete _ptr // 是因为这是移动构造函数,是个构造函数!_ptr 本来就没有资源 p._ptr = nullptr; } UniquePtr &operator=(UniquePtr &&p) noexcept { if (p != *this) { delete _ptr; // 第一步,释放当前资源 _ptr = p._ptr; // 第二步,将当前指针指向新的资源 p._ptr = nullptr; // 第三步,将原来的指针置空 } return *this; } T *get() const { // 返回指针 return _ptr; } T *operator->() const { // 返回指针 return _ptr; } T &operator*() const { // 解引用 return *_ptr; } T *release() { // 这里不能 delete _ptr // 因为 release 只是解除 UniquePtr 对资源的所有权,但资源还是存在的 T *tmp = _ptr; _ptr = nullptr; return tmp; } void reset(T *newptr = nullptr) { if (_ptr != newptr) { delete _ptr; // 释放当前资源 _ptr = newptr; // 指向新资源 // 这里不需要置空 newptr // 是否置空 new ptr 由用户决定 } } }; UniquePtr &operator=(UniquePtr &&p) 移动赋值运算符的原理如下图: ...

2024年06月29日 · 1 分钟 · Cassius0924

C++ 对象和指针的区别学习笔记

对象MyClass obj; obj.fun(); obj.count = 10; 对象是类的实例,占据实际的内存空间,可以调用类的成员函数和访问类的成员变量。 对象大小 = 成员变量大小 + 对齐填充 指针MyClass *p = new MyClass; p->fun(); p->count = 10; 指针是一个变量,存储对象的地址,可以通过指针访问对象的成员函数和成员变量。 指针大小 = 4 字节(32 位系统)或 8 字节(64 位系统) 对象和指针的区别 内存管理 对象:内存分配和释放通常是自动的(除非使用动态分配)。 指针:指向的内存需要手动管理,尤其是动态分配的内存。 访问方式: 对象:直接访问成员。 指针:通过解引用访问成员(使用 -> 操作符)。 生命周期: 对象:由作用域决定,局部对象在离开作用域时自动销毁。 指针:生命周期由程序员控制,指针可以指向任何作用域的变量。

2024年06月28日 · 1 分钟 · Cassius0924