【发布时间】:2016-01-18 16:34:43
【问题描述】:
我已经做了一个非常简单的vector实现。我承认我作弊很多,唯一的实例变量是 size_t sz 和 T * elem。许多问题之一(但这是我所知道的唯一可能导致崩溃的问题)是pop_back() 的问题。
template <typename T>
void vec<T>::pop_back() {
if (sz == 0)
return;
elem[sz-1].~T();
--sz;
}
向量elem 是一个动态分配的数组,但数组中的对象可能是也可能不是。我在这里看到的问题是,如果我销毁这个数组中的一个对象,这可能会崩溃。如果我多次破坏元素,就会发生这种情况。可以这么说,以防我使用了 pop_back。我的编译器似乎没有发生这种情况(这看起来很奇怪),但我听说有人在使用这个函数时遇到了这个问题。我一直在尝试在网上做一些研究,发现另一个alternative。这里没有做零校验(可能是懒惰),本例使用reinterpret_cast
template<class T>
void Vector<T>::pop_back() {
// You way want to do a check for empty() before calling the destructor.
// Call the destructor.
(reinterpret_cast<T*>(buffer)[_size-1]).~T();
// It is usual to prefer the pre decrement (and pre increment).
--_size;
}
问题是,我真的可以使用 reinterpret_cast 来销毁向量类中的非动态分配对象吗?
编辑
根据要求,我将展示我的 push_back,我不确定如何在短时间内正确编写它。我承认该类的主要目的不是效率,而是一种处理资源而不是原始动态数组的好方法(我当然可以使用向量,但这是一个关于更小的范围而不是一般策略的问题,所以如果省略了 use-std::vector 讨论)
template <typename T>
void vec<T>::push_back(const T& obj) {
T* tmp = new T[sz+1];
if (sz > 0){
uninitialized_copy(elem, elem+sz, tmp);
delete[] elem;
}
elem = tmp;
elem[sz] = T{obj};
++sz;
}
主要问题是容量。我意识到容量部分需要大量工作,没有它我只能创建新元素。
【问题讨论】:
-
您引用的示例使用“无类型”
char *缓冲区以避免不必要的 ctor 调用,因此转换为T*。相比之下,您的数组elem已经输入,我接受。并且直接在对象上调用 dtor 与动态分配无关。 (由于该对象似乎驻留在您的 elem 向量中,您应该知道它的分配方式;-)。 ) -
我会更担心
T没有析构函数的情况。例如int的向量。如果T是int那么var.~int()没有意义。 -
您能否详细说明一下您所说的“向量元素是一个动态分配的数组,但数组中的对象可能是也可能不是。”?你的数组究竟是如何分配的,你的对象是如何构造的?
-
显示你的 push_back()
-
@CrazyEddie:
var.~int()可能没有意义,但如果 T 是一个模板参数,int就可以了。这只是一个空操作。
标签: c++ reinterpret-cast