在类的构造函数中初始化一个二维向量。

3
我想在类的构造函数中初始化一个2D数组,但编译器给出了这个错误:“调用一个类类型的对象,没有适当的operator()函数或指向函数类型的转换函数”。
class Matrix
{

public:
    Matrix() {};
    Matrix(size_t x, size_t y) { a(x, vector<int>(y , 0 )); }
private:
    vector<vector<int>> a; 


};

成员初始化的正确语法是构造函数初始化列表。 - SergeyA
1
为了实现矩阵,我建议使用一维数组。你只需要一个一维的内存布局来实现矩阵。然后,operator[] 将通过映射到一维向量中的二维坐标来访问正确的元素。 - Guillaume Racicot
3个回答

6

首先,如前所述,这个:

Matrix(size_t x, size_t y)
{
   a(x, vector<int>(y , 0 ));
}

这不是初始化成员的正确方式。要初始化成员,我们使用成员初始化列表,如下所示:

Matrix(size_t x, size_t y)
   : a(x, vector<int>(y , 0 ))
{}

冒号语法是列举初始化的特定位置。构造函数体内部没有任何初始化过程。当您没有为成员指定初始化值时,将进行默认初始化。然后运行构造函数体内的代码。我们知道,函数体由执行的语句组成。

现在,当您执行语句<name>(<thing>, <other thing>)时,那是一个函数调用。如果<name>不是函数而是类实例,则会查找函数调用运算符operator()。如果没有找到该运算符(或与参数不匹配),则编译失败,就像您观察到的那样。

语言是否可以被设计成在构造函数体内以这种形式提及成员时视为初始化?可能可以。但是为什么呢?现在你就没有明确的方法来执行函数调用,且在构造期间发生的顺序也不清楚。现在的方式要好得多。


2
当控制权传递给构造函数的主体时,向量已经被创建。
因此,这个语句
a(x, vector<int>(y , 0 ));

这不是调用向量构造函数。该向量已使用默认构造函数创建,上述语句无效。

您可以在构造函数中使用mem-initializer列表

Translated:

这不是调用向量构造函数。该向量已经使用默认构造函数创建,因此上述语句无效。

您可以在构造函数中使用mem-initializer列表。

class Matrix
{
public:
    Matrix() {};
    Matrix(size_t x, size_t y) : a(x, vector<int>(y ) ) {}
private:
    vector<vector<int>> a; 
};

或者你可以在构造函数的主体中使用成员函数assign。最初的回答
class Matrix
{

public:
    Matrix() {};
    Matrix(size_t x, size_t y) { a.assign (x, vector<int>(y ) ); }
private:
    vector<vector<int>> a; 
};

2

正确的语法是使用初始值列表:

Matrix(size_t x, size_t y):a(x,vector<int>(y,0)) {}

最初的回答。


1
@SergeyA 在这个挑剔的级别上,它被称为_member initializer list_。此外,您不应该对非代码使用代码格式:它对屏幕阅读器(以及使用它们的人)有害。 - Lightness Races in Orbit
因为那不是初始化事物的方式。 - Lightness Races in Orbit
1
@ArisKoutsoukis:“为什么我不能像在代码中那样初始化它?”——它工作了吗?你发问的原因不是因为它没有工作吗? - WhozCraig
@WhozCraig 是的,但我想知道为什么它不能像那样工作。 - user11285615
1
“因为标准文件如此规定”是这样的理由。构造函数体的行为与任何其他函数相同,因此a(x, vector<int>(y , 0 ));意味着调用名为“a”的方法。只有初始化列表是特殊的,构造函数体不能执行任何其他成员函数无法执行的操作。 - Yksisarvinen
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接