5
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++处理这个问题。搜索了几天,请告诉我C++可以做到这一点吗?

4

3 回答 3

16

您需要使用成员初始化列表

B(int v):a(v)
{
}

和:

B(int v) 
{
        a = A(v); // i think this is the key point
}

a正在被分配一个值并且没有被初始化这是你想要的),一旦构造函数的主体开始{,它的所有成员都已经被构造了。

为什么会出现错误?
编译器a在构造函数体{开始之前构造,编译器使用无参数构造函数,A因为你没有告诉它注 1,由于默认的无参数构造函数不可用,因此错误。

为什么没有隐式生成默认的无参数构造函数?
一旦您为您的类提供了任何构造函数,就不会再生成隐式生成的无参数构造函数。您为构造函数提供了重载,A因此没有隐式生成无参数构造函数。

注意 1
使用成员初始化器列表是告诉编译器使用构造函数的特定重载版本而不是默认的无参数构造函数的方法。

于 2012-05-28T11:24:37.113 回答
7

您必须使用初始化列表:

class B {
public:
    B(int v) : a(v) { // here

    }

private:
    A a;
};

否则编译器将尝试A使用默认构造函数构造一个。由于您不提供,因此您会收到错误消息。

于 2012-05-28T11:24:53.023 回答
2

是的,它可以,但你没有提供一个默认的构造函数A(一个不带参数或所有参数都有默认值的),所以你只能在初始化列表中初始化它:

B(int v) : a(v) 
{
}

这是因为在构造函数主体进入之前,a将使用默认构造函数(不可用)来构造(或尝试构造)。

于 2012-05-28T11:24:00.183 回答