当声明 类 的数组时,具有多个参数的构造函数抛出 'expression list treated as compound expression in initializer'

Constructor with multiple parameters throws 'expression list treated as compound expression in initializer' when array of classes declared

我创建了以下测试程序来演示我似乎无法解决的错误。我搜索并阅读了几篇文章,但我发现 none 解释了如何解决这个特定问题。

我创建了一个 class 具有多个构造函数,其中一个具有多个参数。我可以声明 class 测试每个构造函数的实例,但是当我声明一个 classes 数组时,我只能使用默认构造函数或带有单个参数的版本。

当我创建 classes 数组并尝试使用多参数构造函数时,出现编译错误:“表达式列表在初始化程序 [-fpermissive] 中被视为复合表达式”。我正在使用 C++11 mingw 编译器,请参见下面示例程序中的 kc5。

任何人都可以解释错误的含义以及当构造函数具有多个参数时如何正确声明 class 个对象的数组吗?

#include <iostream>
using namespace std;

class KClass {
public:
int x=0;

KClass(){};//default constructor w/o parameters works

KClass(int a){//single parameter constructor works
x = a;
return;
}

KClass(char c,int a){//multi parameter constructor
x = a;
//not using char c for now
return;
}

~KClass(){};//destructor

int getx(){return x;}
void setx(int data){x=data;return;}
};

//class is declared, let's create some instances of the class
KClass kc0;//works
KClass kc1(5);//works
KClass kc2('k',7);//works
KClass kc3[2];//works
KClass kc4[2](4);//works
//next line does not compile (how do I fix?)
KClass kc5[2]('r',4);//compile error: expression list treated as compound expression in initializer

int main()
{
//do something

  getchar();
  return 0;
}

我知道使用 'new' 关键字是可行的,但是,这个解决方案对我来说似乎并不优雅,我不明白为什么需要 'new'。

KClass *kc6 = new KClass[2]; //works

然后在 main() 中使用多参数构造函数进行初始化。

kc6[0] = KClass('a',2);
kc6[1] = KClass('b',3);

这样一个数组的初始化

KClass kc5[2]('r',4);

是 C++ 20 标准允许的。在这种情况下,将为每个元素调用具有一个参数的构造函数。

如果编译器不支持 C++ 20 标准,则会出现错误。

否则在 C++ 20 中你还可以编写

KClass kc5[2]( { 'r',4 } );

并且对于第一个元素,将调用具有两个参数的构造函数。

感谢弗拉德的回答。我想补充一点,我学习了如何使用 C++11 标准(下面的示例程序)使它工作。

看来我的问题是由于不知道在数组中使用多参数构造函数时要使用的正确语法。示例程序显示了有效的方法和意外的结果。

因为我在堆上创建了 3 个 class 对象,所以我在程序终止之前小心地删除了这些对象以避免内存泄漏(初学者请注意)。

#include <iostream>
using namespace std;

class KClass {
public:
int x=0;

KClass(){
cout << "default constructor called" << endl;
};//default constructor w/o parameters works

KClass(int a){//single parameter constructor works
x = a;
cout << "single parameter constructor a: " << a << endl;
return;
}

KClass(char c,int a){//multi parameter constructor
    cout << "visiting multi param constructor c: " << c << " a: " << a << endl;
x = a;
//not using char c for now
return;
}

~KClass(){
cout << "default destructor" << endl;
};//destructor

int getx(){return x;}
void setx(int data){x=data;return;}
};

//class is declared, let's create some instances of the class
KClass kc0;//works default constructor
KClass kc1(5);//works single parameter constructor
KClass kc2('k',7);//works multi parameter constructor
KClass kc3[2];//works default constructor called twice
KClass kc4[2](4);//works single parameter constructor called twice

//next line does not compile (how do I fix?)
//no compile: KClass kc5[2]('r',4);//compile error: expression list treated as compound expression in initializer

KClass *kc6 = new KClass[2];//defaullt constructor called twice

//notice the syntax needed to call the multiparameter constructor twice
KClass *kc7 = new KClass[2]{{'c',8},{'g',9}};//works  multi parameter constructor called twice

//next line calls the single parameter constructor twice; the char 'd' is treated as int 100 (its ascii int value)
KClass *kc8 = new KClass[2]{'d',6};//works but not as expected single parameter constructor called twice

int main()
{
//do something
kc6[0] = KClass('a',2);
kc6[1] = KClass('b',3);
//use kc7 to prove it worked
cout << "kc7[0].getx(): " << kc7[0].getx() << endl;
cout << "kc7[1].getx(): " << kc7[1].getx() << endl;
cout << endl;
cout << "kc8[0].getx(): " << kc8[0].getx() << endl;
cout << "kc8[1].getx(): " << kc8[1].getx() << endl;
cout << endl;

//because we used the new keyword for kc6, kc7 and kc8:
//those objects are on the heap (vs the stack) so we must manually delete to avoid memory leak
delete []kc6;
kc6=nullptr;
delete []kc7;
kc7=nullptr;
delete []kc8;
kc8=nullptr;

  getchar();
  return 0;
}