以下代码仅用于说明我的问题.
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.
您需要使用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++标准库容器使用.