6
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;
}

compiler says:

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&)

I've learned Java, and I don't know how to deal with this in C++. Searching for a couple days, plz tell me can C++ do this?

Scottie
  • 1,021
  • 2
  • 14
  • 22

3 Answers3

16

You need to use a Member Initialization List

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

With:

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

a is being assigned a value and not being initialized(which is what you intend), Once the body of an constructor begins {, all its members are already constructed.

Why do you get an error?
The compiler constructs a before constructor body { begins, the compiler uses the no argument constructor of A because you didn't tell it otherwiseNote 1, Since the default no argument constructor is not available hence the error.

Why is the default no argument constructor not generated implicitly?
Once you provide any constructor for your class, the implicitly generated no argument constructor is not generated anymore. You provided overloads for constructor of A and hence there is no implicit generation of the no argument constructor.

Note 1
Using Member Initializer List is the way to tell the compiler to use particular overloaded version of the constructor and not the default no argument constructor.

Community
  • 1
  • 1
Alok Save
  • 202,538
  • 53
  • 430
  • 533
7

You have to use initialization lists:

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

    }

private:
    A a;
};

Otherwise the compiler will try to construct an A using the default constructor. Since you don't provide one, you get an error.

mfontanini
  • 21,410
  • 4
  • 65
  • 73
2

Yes it can, but you haven't provided a default constructor for A(one that takes no parameters or all parameters have default values), so you can only initialize it in the initializer list:

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

This is because before the constructor body enters, a will be constructed (or attempted to be constructed) with the default constructor (which isn't available).

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625