Reputation: 1279
if we compiled the following code, the compile would complain "no matching function for call to 'fruit::fruit()' "
i think the reason is : apple constructor call a default fruit constructor and it can't find one
but if I removed apple constructor(commented out from LineA to LineB) and compiled again. it is compiled without error. why? from book, if we didn't define any constructor for apple class. the compiler will create one. why the apple default constructor created by compiler doesn't complain about missing fruit::fruit() . thanks
class fruit
{
public:
int seed;
//fruit()
//{
// cout <<"fruit" <<endl;
// seed = 12;
//}
fruit(int i)
{
cout <<i<<"fruit"<<endl;
}
virtual void plant()
{
cout << "fruit" <<endl;
}
};
class apple:public fruit
{
public:
apple() //lineA
{
//cout << "apple" << endl;
} //lineB
void plant()
{
cout << "apple" << endl;
}
};
int main(){}
thanks
I know how to make this code work. my question is why removing the apple default constructor doesnt cause compilation error.
Upvotes: 0
Views: 6292
Reputation: 1
The first thing is, the compiler needs to insert code to call the default constructors of base classes and hence it requires a default constructor of base class otherwise throws an error: "no matching function for call ".
Now coming to the question that why it does not throw an error if apple() constructor is removed and compiled again because as per concept compiler automatically creates a default constructor if not user defined.
In function 'int main()':
error: use of deleted function 'apple::apple()'
note: 'apple::apple()' is implicitly deleted because the default definition would be ill-formed
Upvotes: 0
Reputation: 6834
[ C++11 standard.]
12.1.5. If there is no user-declared constructor for class X, a constructor having no parameters is implicitly declared as defaulted (8.4).
12..1 ..."The implementation will implicitly define them if they are odr-used"...
So, if you remove apple::apple()
, the implementation may not create apple::apple()
unless it is actually called, and hence has no need to reference fruit::fruit()
.
As given, the code does not call apple::apple()
.
Upvotes: 1
Reputation: 121
If you explicitly define a constructor, you are overriding the default one. In this case you defined one with one parameter in fruit class. Now, when you create an object of class apple, the way inheritance behaves is the following: 1. call the constructor of the base class (fruit class). In this case it will call default constructor of the base class since you are not explicitly calling the constructor with one argument of fruit 2. execute constructor of derived class i.e. apple class
The compiler will not be able to find the default constructor of base class (in step 1), hence this error. Solution is to either call constructor of fruit class with one argument in apple class or to define a constructor with no arguments or remove both, whatever suits your needs.
Let us know if you need help with the code or more explanation (code not included with an intention that you will try to understand the OOP concepts).
Upvotes: 0
Reputation: 2204
I think what you need is an initialization list. You need to explicitly call
class apple:public fruit
{
public:
apple() : fruit(10)
{
//cout << "apple" << endl;
}
void plant()
{
cout << "apple" << endl;
}
};
See http://www.cprogramming.com/tutorial/initialization-lists-c++.html for more details.
Upvotes: 0
Reputation: 7961
You need to have default constructor for fruit or setup an id from apple. So either
fruit::fruit() {}
or
apple::apple() : fruit(1) {}
from book, if we didn't define any constructor for apple class. the compiler will create one. why the constructor created by compiler doesn't complain about missing fruit()
Because you have explicitly declared a constructor.
Upvotes: 0