我的班级中析构函数之间的区别

问题描述

我正在实现一个简化的唯一指针。一切都很清楚,但我想知道我班上的析构函数

应该是~unique_pointer(){obj->~T();}还是~unique_pointer(){delete obj}

我真的看不出这些有什么区别。你能解释一下它们是如何工作的吗?

以下是全班:

template<class T>
class unique_pointer{
private:
    T*obj;
public:
    unique_pointer(const T* obj):obj{obj}{}
    ~unique_pointer(){obj->~T();}
    
    T operator*() const { return *obj; }
    T* operator->() const { return obj; }

    T* release(){
        T* temp = obj;
        obj = 0;
        return obj;
    }
};

解决方法

它应该是 ~unique_pointer(){obj->~T();} 或 ~unique_pointer(){delete obj}。我真的看不出彼此之间的区别。

obj->~T() 销毁指向的对象。如果对象存储在动态内存中,则不会释放内存。如果没有其他任何事情释放内存,那么内存就会泄漏。考虑到唯一指针的目的是管理动态分配,这样做是没有意义的。

delete obj 如果 obj 是通过分配 new 创建的,那么这会破坏对象并释放释放。否则程序的行为是未定义的。这就是 std::default_delete 的默认删除器 std::unique_ptr 所做的(除非模板类型参数是 T[],在这种情况下它会调用 delete[])。

适用于大多数情况的一些简单经验法则:

  • 如果你是新的,那就删除
  • 仅在您更新时删除
  • 不要多次删除
  • 如果你新建了一个数组,那么用 delete[] 代替
  • 除非在智能指针或类似的低级内存管理类的实现中,否则不要使用 new 或 delete
  • 如果你malloc,那么free
  • 永远不要多次免费
  • 不要 malloc
  • 如果放置 new,则显式调用析构函数
  • 除非您知道自己在做什么,否则不要放置新的

附言您的 release 似乎没有意义,因为它没有释放 obj,有一个未使用的变量 temp,并且使用了一些未声明的 val

此外,它是可复制的,并且在复制或移动时具有未定义的行为。唯一指针不应该是可复制的,并且需要自定义定义才能移动。