在下面的代码中,B类的成员类型为A类(varA1)。我想创建一个B类对象,其中成员varA1旨在使用A类中的非默认构造函数A(int v1)。
#include <iostream>
using std::cout; using std::endl; using std::string;
class A {
public:
A() { cout << "A default constructor" << endl;}
A(int v1);
private:
int var1;
};
A::A(int v1) {
cout << "A int constructor" << endl;
var1 = v1;
}
class B {
public:
B() { cout << "B default constructor" << endl;}
B(int v1);
private:
int var1;
A varA1;
};
B::B(int v1) {
cout << "B int constructor" << endl;
var1 = v1;
A varA1(int v1);
}
int main()
{
A TestA(1);
B TestB(1);
return 0;
}
但是,当我运行上面的代码时,我得到以下输出:
A int constructor
A default constructor
B int constructor
我一定是在做错了。我需要更改什么才能让B类在A类中使用非默认构造函数A(int v1)?
我使用的是ubuntu 14.04LTS。 GNU G ++ 4.9和5.1都给出了相同的结果。
提前感谢您阅读和回答。
答案 0 :(得分:4)
B::B(int v1) : var1(v1), varA1(v1) {
cout << "B int constructor" << endl;
}
请注意,成员按照他们在类中声明的顺序进行初始化(构建),因此成员初始化列表中的切换顺序不会改变构造发生的顺序(希望您的编译器会警告你这个)。如果您尝试从varA1
构建var1
并在类定义中var1
之后声明varA1
,则此细节变得非常重要。
顺便说一下,所有这一行都在(B::B(int v1)
构造函数内):
A varA1(int v1);
是forward,声明一个名为varA1
的函数,该函数接受int
参数并返回A
个对象。这与most vexing parse类似,但这并不是最令人烦恼的解析。
答案 1 :(得分:1)
您可以在B :: B(int)构造函数中使用初始化列表:
B::B(int v1) : varA1(v1) {
cout << "B int constructor" << endl;
var1 = v1;
}
答案 2 :(得分:0)
如果您不想使用默认ctor,可以使用
A(void) = delete;
但请注意,您可以暂时将此声明添加为诊断措施,以使编译器通知您要使用默认ctor的代码。
替换
A() { std::cout << "A default constructor" << std::endl;}
与
A() = delete;
编译器会抱怨在B :: B(int v1)的主体中使用已删除的函数'A :: A()'。
因此,简要检查确定B的第二个数据属性,即“B :: varA1”,使用A的默认ctor(现已删除)。
您也可以考虑通过在B ctor的初始化列表中显式调用“varA1(0)”来“修复”B不要使用A的默认ctor。