简体   繁体   中英

C++ inheritance: child class instance uses both child and parent constructors

I am practicing inheritance in c++ and I am having some constructor issues.

When I create an instance of the child class (Circle), it creates an instance of both child and parent. Or does it?

I would like to ONLY create an instance of Circle instead of both shape and circle.

If I remove the : Shape(0,0) from Circle's constructor, then I get the error: "no default constructor exists for class Shape"

Do you always have to reference parent's constructor? And that means that the parent's constructor is always called? Does that mean that there is an instance of both child and parent?

Child Class:

#include "Circle.h"
#include <iostream>

using namespace std;

Circle::Circle(float radius) : Shape(0.0, 0.0) {
   this->radius = radius;
}

float Circle::computeArea() {

    cout << "Circle area is " << (3.14 * radius * radius) << "\n";
    return float(3.14 * radius * radius);
}

Parent package:

#include "Shape.h"
#include <iostream>

using namespace std;

Shape::Shape(float base, float height) {
   this->base = base;
   this->height = height;

   cout << "Shape: base - " << base << " height - " << height << "\n";
}


float Shape::computeArea() {

   cout << "Area is " << base*height << "\n";
   return base * height;
}

Main package:

#include "Circle.h"
#include "Square.h"
#include <iostream>

using namespace std;


int main() {

    Square mySquare(10.0, 10.0);
    Circle myCircle(5.0);

    float squareArea = mySquare.computeArea();
    float circleArea = myCircle.computeArea();

    cout << "done";


    return 0;
}

Output:

Shape: base - 10 height - 10
Shape: base - 0 height - 0
area is 100
circle area is 78.5
done

I think you are confusing terminology. Namely, you are confusing a parent, which is a role, with a base class.

If a circle is a shape, then of course by creating a circle you will also be creating a shape, because the circle is a shape. It is unavoidable and entirely correct. But shape won't be an extra object, it will be contained within the circle, an integral part of it.

Do you always have to reference parent's constructor?

Not always, if you have a default constructor, either one with no parameters or with parameters defaults, you can omit it and get the default constructor implicitly. But since Shape has only one constructor that takes parameters, you have to specify it. A circle is a shape, so before you can have a circle, you must have a shape.

If you change the constructor to Shape::Shape(float base = 0.0, float height = 0.0) you can omit it from the initialization list of the derived class.

A parent is something entirely different from a base class, parent-child relations are about ownership, for example in the case of deterministic garbage collection, when the lifetime of children is tied to the lifetime of the parent.

It doesn't seem to me you have a problem with your code, you're just confused about how inheritance works in C++.

Every time you derive a class from a base class, before entering in the subclass constructor, the compiler automatically calls the base class constructor for you if it has no arguments. For example, if your Shape class had a constructor like this

Shape::Shape(){ }

then the subclass wouldn't have to call the base class constructor in the initialization list (the compiler does that for you). Now your constructor can look like this:

Circle::Circle(float radius) {
   this->radius = radius;
}

If you don't have a constructor without parameters you must explicitly call it in the initialization list.

Every object of type Circle is a kind of Shape with more information inside. This doesn't mean the compiler creates two objects just because it initializes also the parent's components, you still have one object.

Now, if you want your Circle to be different from your Shape object then you don't need the inheritance anymore. (Although I assume this is not what you want)

You can not/ don't want to avoid calling the base class constructor, that's the whole point of inheritance: it allows you to extend the characteristics of one object, which is based on another object's implementation.

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