我将vector定义为Grid类的私有变量。 Class 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;
};
我应该使用哪个选项并正确初始化构造函数?
答案 0 :(得分:9)
如果没有使用new
分配对象,则无需明确销毁它。
成员对象将按其声明的相反顺序自动销毁。在你的情况下,甚至不需要创建析构函数,因为自动化就足够了。
如果出于某种原因,您确实使用new分配了成员对象,则还必须创建自定义复制构造和赋值运算符,否则会遇到跨多个实例共享同一成员对象的麻烦。
答案 1 :(得分:1)
我会回复,因为在您提出更多问题时前辈们只回答了主题中的问题,我也会给出一些建议。在本文的其余部分中,我们假设如果Points
确实分配了任何动态内存,则在删除Points
时会正确返回内存。
Class 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类成员来说,它没有任何区别,只是风格问题。对于类的类成员,它避免了对默认构造函数的不必要的调用。
我是否正确地初始化构造函数以及编写析构函数时 对于Grid,我需要为这样的向量编写析构函数: ~vecotr()或删除或使用迭代器?
您不初始化构造函数,而是在构造函数初始化列表中初始化类成员。由于向量未使用new
分配,因此您不会delete
(调用delete
)。当Grid
被销毁时,它将被自动销毁。
答案 2 :(得分:1)
// fourth (and correct) option:
~Grid() {
}
或者完全忽略析构函数;编译器生成的析构函数将在这里做正确的事。
如果使用new
创建对象,则必须将其删除。如果你不这样做,你就不能。
答案 3 :(得分:0)
我假设Points
没有任何动态分配的内存。如果是这种情况,那么您只需要
~Grid() { }
如果确实如此,则需要为向量中的每个项删除动态分配的内存(或使用智能指针)。