简体   繁体   中英

Can constructor call another class's constructor in c++?

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?

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 otherwise Note 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.

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM