【问题标题】:pop_back and erase for a vector class C++向量类 C++ 的 pop_back 和擦除
【发布时间】:2016-06-09 00:57:19
【问题描述】:

我正在尝试为我的向量类编写 pop_back 和擦除成员函数。但是我意识到我不能使用删除。关于如何摆脱元素的任何建议?

template <class T>
class Vector{
private:
int current_size, capacity;
T* arr;

public:

Vector();
unsigned int size();
void grow();
void push_back(const T& elt);
void pop_back();
T& at(int pos);
T& front();
T& back();
bool empty();
void insert (const T&elt, int pos);
void erase(int pos);
Vector<T>& operator=(const Vector& v);
T& operator[](int n);

};

template <class T>
void Vector<T>::pop_back(){
if(!empty()){
    delete arr[current_size-1];
    current_size--;
    }
 }

template <class T>
void Vector<T>::erase(int pos){
if(!empty() && pos>=0 && pos<current_size) {
    for (int i=pos; i<(current_size-1); i++){
        arr[i]=arr[i+1];
    }
    delete arr[current_size-1];
    current_size--;
 }
}

【问题讨论】:

  • 为什么deleteVector中的最后一个元素,而不是arr[pos]循环前Vector&lt;T&gt;::erase()中要删除的元素?
  • 您是如何意识到不能使用 delete 的?编译错误?运行时错误?主管告诉的?
  • @MikeCAT 第一个问题:因为他只是将它们移动了一个。第二个问题:可能是编译错误,因为arr[current_size-1] 不是指针。
  • 您将为此使用 placement new 和 delete。不过,这取决于您如何实现grow。这也可能是痛苦的问题。正确编写矢量风格的容器并非易事。

标签: c++ arrays templates vector


【解决方案1】:

要在未分配常规 new 的对象上调用析构函数,您可以执行以下操作:

arr[current_size-1].~T();

请记住,在分配数组中的对象时,您可能还希望确保在它们上也调用placement new,否则您正在处理未初始化的对象。例如:

new (&arr[some_index]) T();

(您需要包含头文件&lt;new&gt; 来执行此操作)

【讨论】:

  • 唯一的问题是自己也必须创建析构函数。所以这让我回到了如何摆脱这些元素的同一个问题。
  • 我不明白这个问题。我发布的代码调用了析构函数,然后你已经减少了向量上的大小变量。当然,你仍然分配了内存,但你没有使用它,这就是向量的工作方式。
  • 如果询问者使用new T[]delete[] 分配和删除数组,这是一个不好的建议。
  • 如果他这样做,那么他的问题就更大了。使用new T[] 将立即构造对象,这不是您想要的向量。
  • 只是给出一个更大的图景:如果你想让你的代码更像一个向量,你 1) 分配原始内存,2) 将对象构造到该内存中,并放置 new。 3) 通过单独调用它们的析构函数来销毁对象。 4) 在销毁其中包含的所有对象后释放整个原始内存块。如果需要,您可以直接执行这些操作,或者通过分配器对象(std::vector 就是这样做的)。
猜你喜欢
  • 1970-01-01
  • 2020-12-21
  • 1970-01-01
  • 2017-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-17
  • 1970-01-01
相关资源
最近更新 更多