C++组合模式中对象数组初始化报错问题咨询
问题解答
代码与错误信息
出错代码
#define NUMBER (4) class wheel { int radius; public: wheel(); wheel(int); //copy constructors prototype //getters and setters prototypes }; wheel::wheel() : radius(1) {} wheel::wheel(int r) : radius(r) {} //wheel class copy constructor definition //wheel class setter and getter definitions class car { wheel fourwheels[NUMBER]; public: car(); }; car::car() { fourwheels[NUMBER] = {wheel(1), wheel(1), wheel(1), wheel(1)}; //error code //wheel fourwheels[NUMBER] = {wheel(1), wheel(1), wheel(1), wheel(1)}; //non-error code } int main() { car mycar; return 0; }
编译错误
error: no match for 'operator=' (operand types are 'wheel' and '<brace-enclosed initializer list>')
问题1:错误为何发生?
有两个核心原因:
- 首先,
fourwheels[NUMBER]是访问数组的第NUMBER个元素,但数组下标从0开始,fourwheels的有效下标范围是0到3,这里属于越界访问不存在的wheel对象。 - 其次,就算下标合法,你试图给单个
wheel对象赋值一个包含4个wheel实例的初始化列表,C并没有为wheel类定义能接受这种初始化列表的赋值运算符operator=,编译器找不到匹配的赋值逻辑,因此报错。另外补充:C里数组无法直接用=进行整体赋值,只能在数组定义阶段用初始化列表完成初始化。
问题2:为何数组定义时必须添加wheel类型?
你取消注释的代码是在构造函数里定义一个新的局部数组变量,而非操作类的成员数组。C++语法规则明确要求:任何变量(包括数组)在声明时必须指定类型,wheel就是告诉编译器这个数组的每个元素都是wheel类型,这是变量声明的必要组成部分。
注意:这段非报错代码里的fourwheels是构造函数的局部变量,会覆盖类成员的fourwheels,如果你的目的是初始化类的成员数组,正确写法应该用构造函数初始化列表:
car::car() : fourwheels{wheel(1), wheel(1), wheel(1), wheel(1)} {}
内容的提问来源于stack exchange,提问作者Pisers
相关产品推荐
相关产品推荐

