class A {
public:
A(int v) {
_val = v;
}
private:
int _val;
};
class B {
public:
B(int v) {
a = A(v); // i think this is the key point
}
private:
A a;
};
int main() {
B b(10);
return 0;
}
编译说:
test.cpp: In constructor ‘B::B(int)’:
test.cpp:15: error: no matching function for call to ‘A::A()’
test.cpp:5: note: candidates are: A::A(int)
test.cpp:3: note: A::A(const A&)
我已经学习了Java,而且我不知道如何在C ++中处理这个问题。 搜索了几天,PLZ告诉我C ++可以这样做吗?
答案 0 :(得分:15)
您需要使用 Member Initialization List
B(int v):a(v)
{
}
使用:
B(int v)
{
a = A(v); // i think this is the key point
}
a
正在 分配 一个值而不是已初始化(这是您想要的 >),一旦构造函数的主体开始{
,其所有成员都已构建。
为什么会出错?
编译器在构造函数体a
开始之前构造{
,编译器使用A
的无参数构造函数,因为你没有告诉它否则注1 ,因为默认的无参数构造函数不可用因此错误。
为什么隐式生成默认的无参数构造函数?
为类提供 任何 构造函数后,将不再生成隐式生成的无参数构造函数。您为A
的构造函数提供了重载,因此没有隐式生成无参数构造函数。
注1
使用Member Initializer List是告诉编译器使用构造函数的特定重载版本而不是默认的无参数构造函数的方法。
答案 1 :(得分:6)
您必须使用初始化列表:
class B {
public:
B(int v) : a(v) { // here
}
private:
A a;
};
否则编译器将尝试使用默认构造函数构造A
。由于您没有提供,因此会出错。
答案 2 :(得分:2)
是的,但是你没有提供A
的默认构造函数(一个不带参数或者所有参数都有默认值),所以你只能在初始化列表<中初始化它/强>:
B(int v) : a(v)
{
}
这是因为在构造函数体进入之前,将使用默认构造函数(不可用)构造(或尝试构造)a
。