显式析构函数

Sea*_*ean 4 c++ destructor

以下代码仅用于说明我的问题.

template<class T>
class array<T>
{
 public:
    // constructor
    array(cap = 10):capacity(cap)
    {element = new T [capacity]; size =0;}

    // destructor
    ~array(){delete [] element;}
    void erase(int i);
    private:
      T *element;
      int capacity;
      int size;
};



template<class T>
void class array<T>::erase(int i){
     // copy
     // destruct object
    element[i].~T();  ////
    // other codes
} 
Run Code Online (Sandbox Code Playgroud)

如果我array<string> arr在main.cpp.当我使用时erase(5),对象element[5]被破坏但是空间element[5]不会被释放,我可以用来element[5] = "abc"在这里放一个新值吗?或者我是否应该使用placement new来在空间中添加新值element [5]

当程序结束时,arr<string>将调用它自己的析构函数,它也会调用delete [] element.因此,字符串的析构函数将首先运行以销毁对象,然后释放空间.但是因为我已经明确地破坏了element[5],所以析构函数(由arr的destuctor调用)运行两次来破坏element[5]吗?我知道空间不能被解除分配两次,对象怎么样?我做了一些测试,发现如果我只是两次破坏对象而不是两次释放空间似乎没问题.

更新

答案是:

(1)I have to use placement new if I explicitly call destructor.

(2) repeatedly destructing object is defined as undefined behavior which may be accepted in most systems but should try to avoid this practice.

Jam*_*lis 7

您需要使用placement-new语法:

new (element + 5) string("abc");
Run Code Online (Sandbox Code Playgroud)

这是不正确的说element[5] = "abc"; 这将调用operator=on element[5],这不是一个有效的对象,产生未定义的行为.

当程序结束时,arr<string>将调用它自己的析构函数,它也会调用delete [] element.

这是错误的:您将最终调用析构函数来查找已经调用了析构函数的对象(例如,elements[5]在上述示例中).这也会产生未定义的行为.

考虑使用它std::allocator和它的接口.它允许您轻松地将分配与构造分开.它由C++标准库容器使用.