一些简单的代码:
class Thing {
public:
int num;
Thing(int num) {
this->num = num;
}
};
class Stuff {
public:
Thing thing; // an instance of thing is declared here but it cannot construct it
Stuff(Thing thing) {
this->thing = thing;
}
};
int main() {
Thing thing = Thing(5);
Stuff stuff = Stuff(thing);
}
所以在这里,我试图弄清楚我应该如何在Stuff的构造函数中使用Thing的新实例而不指向它,因为我希望Stuff拥有自己的副本。当然,我无法宣布上面的内容,因为它试图初始化它。
如何解决将新对象副本分配给类的问题?变量通过它的构造函数?
确切错误是:
In constructor 'Stuff::Stuff(Thing)':
error: no matching function for call to 'Thing::Thing()'
Stuff(Thing thing){ this->thing = thing; }
candidate expects 1 argument, 0 provided
答案 0 :(得分:13)
问题在于:
Stuff(Thing thing) {
this->thing = thing;
}
当您进入构造函数体时,编译器已经初始化了对象的数据成员。但它无法初始化thing
,因为它没有默认构造函数。
解决方案是告诉编译器如何使用 initlizer list 对其进行初始化。
Stuff(Thing thing) : thing(thing) {
// Nothing left to do.
}
这样打字更少,代码更清晰,效率更高。 (效率更高,因为如果要对变量进行初始化,那么为什么要先用不需要的值初始化它,只是为了尽可能快地分配另一个?当然,因为你当前的代码甚至没有编译,“更多高效“在这里是一个有点可疑的陈述。”
答案 1 :(得分:2)
使用初始化列表初始化Stuff中的东西成员:
class Stuff {
public:
Thing thing; // an instance of thing is declared here but it cannot construct it
Stuff(Thing thing): thing(thing) { }
};
答案 2 :(得分:1)
Thing
的唯一构造函数采用int
参数。
因此,当您声明:
Thing thing;
没有参数,它如何知道num
应该是什么?
如错误所述,预期有1个,但没有提供。您需要添加默认构造函数:
Thing::Thing(void) : num(0){};
或者修改参数:
Thing::Thing(int num=0)
在这两种情况下,我都使用了0
,但是如果没有指定任何内容,那么这应该是您认为num
应该是'默认'的任何内容。
如果没有这个,Stuff
的{{1}}必须有一个值来初始化它;这是通过初始化列表支持的,您忽略了在Thing
中使用(见上文),并且作为旁注,您的Thing::Thing
不是必需的,this->num
就足够了。< / p>
num