【问题标题】:Do I need to delete a vector?我需要删除矢量吗?
【发布时间】:2013-08-30 01:29:50
【问题描述】:

我将向量定义为类 Grid 的私有变量。类 Points 只有两个实例变量,它们都是整数,但是只有当我从文件中读取它时才会知道点的数量,所以我想我必须用 new 动态地制作 Points,这意味着我必须稍后销毁它们。我是否正确初始化了构造函数,在为 Grid 编写析构函数时,我是否需要为向量编写析构函数,如下所示:~vecotr() 或删除或使用迭代器?

class Grid{
public:
  // initialize vector with 3 points with val 0.
  Grid(vector<Points> v) : vector<Points>(3, 0) {};  // is this right


// first option
  ~Grid() {
    ~vector<Points>();  // not sure how to destroy vector<Points>;
  }

// second option
  ~Grid() {
     delete v_points;
  }

// third option
  ~Grid() {
     for (vector<Points>::iterator it = v_points.begin(), 
          vector<Points>::iterator it_end = v_points.end(); it != it_end; it++)
  }

private:
  vector<Points> v_points;
};

我应该使用哪个选项,我是否正确初始化了构造函数?

【问题讨论】:

    标签: c++


    【解决方案1】:

    如果对象不是用new 分配的,则不需要显式销毁它。 成员对象将按照其声明的相反顺序自动销毁。在您的情况下,甚至不需要创建析构函数,因为自动析构函数就足够了。

    如果由于某种原因您确实为成员对象分配了 new,您还必须创建自定义复制构造和赋值运算符,否则您会遇到跨多个实例共享相同成员对象的麻烦。

    【讨论】:

    • @Anycom 好吧,我将调用新点来创建每个新点,那么我应该使用第三个选项吗?
    • @Napalidon,是否有特定原因,而不是在没有new 的情况下这样做?
    • @Napalidon 我不认为你想使用 new 来填充点,除非 Point 是一个指针(我的直觉不是)。
    • @Napalidon 当我开始学习 C++ 时,我也想new 这个那个,因为书本非常强调它。在实践中,我很少使用 new/delete。
    • @Anycorn Point 是一个类,其中包含有关点的信息,如 int x、int y 和 int weight。所以我有点困惑,如果我有一个文件告诉我每个点的这些信息并且我不提前知道这个文件包含多少点,我如何在没有“新”的情况下填充列表?
    【解决方案2】:

    我会回复,因为前辈只回答了主题中的问题,而您提出更多问题,我也会给出一些建议。在本文的其余部分中,我们将假设如果Points 确实分配了任何动态内存,那么当Points 被删除时,内存会正确返回。

    类点只有两个实例变量,它们都是整数,但 只有当我从文件中读取它时,才会知道点数, 所以我想我必须用 new 动态地制作积分,这意味着我 以后必须销毁它们。

    这与你在这里实际做的事情相矛盾

    class Grid{
    public:
      // initialize vector with 3 points with val 0.
      Grid(vector<Points> v) : vector<Points>(3, 0) {};  // is this right
    
    private:
      vector<Points> v_points;
    };
    

    因为你创建了没有new 的向量。但是,如果我们假设您首先获得Points 的编号,然后您将要创建一个网格,这可能没问题。 std::vector 不是 C 数组,可以轻松调整大小、分配并提供更大的灵活性。您不必在堆上创建它,因为您担心大小:向量元素是在堆上创建的always,它只是一个向量本身(如果它是)在堆栈上。这通常正是我们想要的(参见RAII)。那么初始化向量的正确方法是

    class Grid{
        public:
          // initialize vector with 3 Points with val Points(0)
          Grid(vector<Points> v) : v_points(3, Points(0)) {};
    
        private:
          vector<Points> v_points;
    };
    

    注意,我们在初始化列表中进行。对于 POD 类成员来说,这没有什么区别,只是风格问题。对于属于类的类成员,则避免了对默认构造函数的不必要调用。

    我是否正确初始化了构造函数以及在编写析构函数时 对于 Grid 我是否需要为向量编写一个析构函数,如下所示: ~vecotr() 还是使用删除或使用迭代器?

    您不初始化构造函数,而是在构造函数初始化列表中初始化类成员。由于vector没有分配new,你不会delete它(调用delete)。当Grid被销毁时会自动销毁。

    【讨论】:

      【解决方案3】:
      // fourth (and correct) option:
      ~Grid() {
      }
      

      或者完全省略析构函数;编译器生成的析构函数会在这里做正确的事情。

      如果您使用new 创建对象,则必须将其删除。如果你不这样做,你就不能。

      【讨论】:

        【解决方案4】:

        我假设Points 没有任何动态分配的内存。如果是这种情况,那么您所需要的就是

        ~Grid() { }
        

        如果是这样,那么您需要为向量中的每个项目删除动态分配的内存(或使用智能指针)。

        【讨论】:

        • 最好不要将析构函数放入 imo。
        • 所有你需要的是隐式析构函数,它看起来像这样:
        • 我假设张贴者已将问题简化为基本问题,而析构函数将包含其他内容。无论如何,恕我直言,我喜欢明确。
        • @EdHeal 如果我从具有多个点的文件中读取,那么我想我必须动态创建每个点对吗?那么这是否意味着我需要使用第三个选项?
        • @Napalidon,在我看来,这听起来像是最简单的 Point pt; fin &gt;&gt; pt; v_points.push_back(pt);
        猜你喜欢
        • 2012-01-26
        • 1970-01-01
        • 1970-01-01
        • 2018-11-28
        • 1970-01-01
        • 2020-08-05
        • 2015-12-18
        • 1970-01-01
        • 2016-08-09
        相关资源
        最近更新 更多