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

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

本文关键字:构造函数 继承 子类 实例 c++      更新时间:2023-10-16

我在c++中练习继承,我有一些构造函数问题。

当我创建子类(Circle)的实例时,它同时创建了子类和父类的实例。是吗?

我想只创建一个Circle的实例,而不是shape和Circle。

如果我从Circle的构造函数中删除:Shape(0,0),那么我得到错误:"没有默认构造函数存在于类Shape"

总是需要引用父类的构造函数吗?这意味着父类的构造函数总是被调用?这是否意味着存在子节点和父节点的实例?

子类:

#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);
}
父包:

#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;
}

主要计划:

#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;
}
输出:

font - family:宋体
形状:base - 0 height - 0
面积100
圆面积78.5

我想你混淆了术语。也就是说,您混淆了父类(角色)和基类。

如果一个圆是一个形状,那么通过创建一个圆,你当然也会创建一个形状,因为圆是一个形状。这是不可避免的,也是完全正确的。但shape不会是一个额外的对象,它将被包含在圆中,是它不可分割的一部分。

总是需要引用父类的构造函数吗?

不总是这样,如果你有一个默认构造函数,无论是没有参数的还是有默认参数的,你都可以省略它,隐式地获得默认构造函数。但是由于Shape只有一个接受参数的构造函数,因此必须指定它。圆是一种形状,所以在你有一个圆之前,你必须有一个形状。

如果您将构造函数更改为Shape::Shape(float base = 0.0, float height = 0.0),则可以从派生类的初始化列表中省略它。

父类与基类完全不同,父子关系是关于所有权的,例如在确定性垃圾收集的情况下,当子类的生命周期与父类的生命周期相关联时。

在我看来你的代码没有问题,你只是对c++中的继承如何工作感到困惑。

每次从基类派生类时,在进入子类构造函数之前,如果基类构造函数没有参数,编译器会自动为您调用基类构造函数。例如,如果Shape类有如下构造函数

Shape::Shape(){ }

则子类不必调用初始化列表中的基类构造函数(编译器会为您完成)。现在你的构造函数看起来像这样:

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

如果没有带参数的构造函数,必须在初始化列表中显式调用它。

每一个Circle 类型的对象都是一种形状,里面有更多的信息。这并不意味着编译器创建了两个对象,因为它也初始化了父对象的组件,你仍然有一个对象。

现在,如果你想让Circle不同于Shape对象,那么你就不再需要继承了。(虽然我认为这不是你想要的)

你不能/不想避免调用基类构造函数,这就是继承的全部意义:它允许你扩展一个对象的特征,这是基于另一个对象的实现。