简体   繁体   English

C ++继承:子类实例同时使用子构造函数和父构造函数

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

I am practicing inheritance in c++ and I am having some constructor issues. 我在C ++中练习继承,但遇到一些构造函数问题。

When I create an instance of the child class (Circle), it creates an instance of both child and parent. 当我创建子类(Circle)的实例时,它同时创建了子代和父代的实例。 Or does it? 还是呢?

I would like to ONLY create an instance of Circle instead of both shape and circle. 我只想创建一个Circle实例,而不是shape和circle。

If I remove the : Shape(0,0) from Circle's constructor, then I get the error: "no default constructor exists for class Shape" 如果我从Circle的构造函数中删除:Shape(0,0),则会收到错误:“类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 形状:底座-10高度-10
Shape: base - 0 height - 0 形状:底座-0高度-0
area is 100 面积是100
circle area is 78.5 圆圈面积是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. 但是由于Shape只有一个采用参数的构造函数,因此必须指定它。 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. 如果将构造函数更改为Shape::Shape(float base = 0.0, float height = 0.0) ,则可以从派生类的初始化列表中将其省略。

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++. 在我看来,您的代码似乎没有问题,只是对继承在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::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. 每个Circle类型的对象都是一种 Shape,其内部包含更多信息。 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. 现在,如果您希望Circle与Shape对象不同,则不再需要继承。 (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. 您不能/不想避免调用基类构造函数,这就是继承的全部重点:它允许您扩展一个对象的特性,该对象基于另一对象的实现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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