The following code works when run at cpp.sh:
#include <iostream>
class B{
public:
B(int i);
int i;
};
B::B(int i) {
this->i = i;
}
class A{
public:
A(B *b);
B *b;
};
A::A(B *b) {
this->b = b;
}
int main()
{
B b(8);
A a(&b);
std::cout << a.b->i;
}
It creates an object of type B
and stores a pointer in an object of type A
.
What I want to do is to only pass the integer (8 in this case) and create and store the full object in a
without creating an intermediate object.
But when I try to declare a object of type B (not just a pointer) inside A, I get a no matching function for call to 'B::B()
error.
This is the approach I tried, which doesn't work:
#include <iostream>
// B i not changed
class B{
public:
B(int i);
int i;
};
B::B(int i) {
this->i = i;
}
class A{
public:
A(int i);
B b;
};
A::A(int i) {
this->b(i); //initialize
}
int main()
{
A a(8);
std::cout << a.b->i;
}
Why do I get a "no matching function" error when declaring a B b;
variable instead of a pointer B *b;
?
Is my approach this->b(i);
to initialize a member after declaration correct?
Your class B
does not provide a constructor taking no arguments (the implicitly defined default constructor gets deleted once you declare any other constructor).
When you define another class A
with a data member of type class B
, the system cannot initialize this data member unless you explicitly define which constructor of B
with which arguments should be used.
You can overcome this by...
Call the constructor of b
in an member-initializer list of A
's constructor, i.e. A::A(int i) : b(i) {}
Default-Initialize data member b
when defining it, i.e. in A
, write B b = B(1)
;
Define a (user-defined) default constructor in B
, e.g. B() : i(0) {}
Define a default value in the (sole) constructor of B
, e.g. B(int i=0)
I'd prefer option 1; Options 2..4 are listed just for completeness.
Note that any code, regardless which, in the body of a constructor is not considered as "data member initialization".