请看一下这段代码:
template <typename T>
class matrix
{
private:
std::vector<T> vec_;
public:
matrix(size_t rows , size_t cols) : rows_(rows) , cols_(cols) , vec_(rows_ * cols_)
{
}
size_t rows_;
size_t cols_;
};
这是一种声明类的方法。我只是想知道std::vector
的分配位置和初始化位置?
声明变量时会发生什么?在构造函数被调用或在构造函数中分配和初始化之前,是否在堆栈中分配了它的空间?
声明大小为10的向量
之间有什么区别 std::vector<T> vec_(10);
并在构造函数中调用大小为10的vec_的构造函数?
matrix() : vec_(10)
我想了解如何在C ++中分配和初始化对象。
此外,我可以在不调用std::vector
matrix() {}
这里发生了什么?由于我没有调用向量的构造函数,编译器是否将其自己拥有?可以使用矢量对象吗?或者是否自动调用,因为我声明std::vector
是我班级的变量?
初始化为std::vector vec(10)
,与调用resize / reserve具有相同的效果。哪个更接近?
答案 0 :(得分:2)
该代码:
private:
std::vector<T> vec_(10);
博指出,没有编译。但你可以在法律和法律方面做到这一点。 c ++ 11中的高效方式(由于copy elision而具有高性能:赋值运算符很可能会变成复制构造函数,因为对象正在此行初始化):
private:
std::vector<T> vec = std::vector<T>(10);
那么,之前的构造和这一个:
public:
matrix() : vec_(10)
执行相同的操作:vec_
将构建一次,其中包含10个元素,与resize
完全相同,除了它更快,因为您不必创建空向量和调整大小。
对于问题的第二部分:如果使用默认构造函数创建实例,编译器将为所有类成员调用默认构造函数,因此它非常安全。
注意:POD对象没有归零,这可能是一个问题,因此最好将指针设置为nullptr
,将整数设置为0等等...或者您获得未初始化的值,进入析构函数时效果不佳将无效指针传递给delete
...
当然,如果其中一个成员只有非默认构造函数(需要参数),它将无法编译。
答案 1 :(得分:2)
类对象的成员按声明的顺序初始化。在这种情况下,就是这个顺序:
private:
std::vector<T> vec_;
public:
size_t rows_;
size_t cols_;
所以在执行初始化列表时
matrix(size_t rows , size_t cols) : rows_(rows) , cols_(cols) , vec_(rows_ * cols_)
真实的顺序是
vec_(rows_ * cols_), rows_(rows) , cols_(cols)
在初始化之前使用rows_
和cols_
。坏事会发生。