C ++默认构造函数调用

时间:2015-10-31 20:37:52

标签: c++

在下面的代码中,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都给出了相同的结果。

提前感谢您阅读和回答。

3 个答案:

答案 0 :(得分:4)

使用member initialization list

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。