2013-08-30 71 views
0

我将矢量定义为类Grid的私有变量。 Class Points只有两个实例变量都是整数,但只有当我从文件中读取这些变量时才知道点的数量,所以我想我必须动态地用新变量来表示它,这意味着我必须在以后销毁它们。我是否正确地初始化构造函数,并且在为Grid编写析构函数时,是否需要为这样的向量编写析构函数:〜vecotr()或者使用delete或使用迭代器?我需要删除矢量吗?

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; 
}; 

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

回答

8

如果对象没有与new分配,则不需要明确销毁它。 成员对象将按其声明的相反顺序自动销毁。在你的情况下,不需要创建析构函数,因为自动函数就足够了。

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

+0

@Anycom嗯,我会打电话给新的积分来创建每个新点,然后我使用第三个选项? – Napalidon

+0

@Napalidon,是否有一个特定的原因,而不是没有'新'的做? – chris

+0

@Napalidon我不认为你想使用新的填充点,除非点是一个指针(我的预感不是)。 – Anycorn

0

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

~Grid() { } 

如果它不那么你需要删除向量中的每个项目是动态分配的内存(或者使用智能指针)。

+1

更好的是不要把析构函数放在所有imo中。 – chris

+3

所有你需要的是隐式析构函数,看起来像这样: –

+0

我假设海报已经将问题减少到裸露的骨头,并且析构函数将包含其他东西。无论如何,恕我直言,我喜欢明确。 –

0

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

类口岸只有两个实例瓦尔那都是整数,但是当我从文件中读取这个 点数才可得知, 所以我想我必须做出点动态与新意思我以后必须摧毁他们。

这种带有矛盾,你真正在这里做

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类的成员来说,这没什么区别,只是风格问题。对于类成员来说,它避免了对默认构造函数的不必要的调用。

难道我正确初始化构造函数和当编写一个析构函数 网格我是否需要写这样的矢量析构函数: 〜vecotr()或删除或使用迭代器?

您不初始化构造函数,而是在构造函数初始化程序列表中初始化类成员。由于矢量未分配到new,因此您不会拨打delete(请拨打delete)。当Grid被销毁时它会自动销毁。

0
// fourth (and correct) option: 
~Grid() { 
} 

或者只是离开了析构函数完全;编译器生成的析构函数会在这里做正确的事情。

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