我在c ++中练习继承,我遇到了一些构造函数问题。
当我创建子类(Circle)的实例时,它会创建child和parent的实例。或者是吗?
我想只创建一个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;
}
输出:
形状:底座 - 10高度 - 10
形状:底座 - 0高度 - 0
面积是100
圆圈面积为78.5
完成了
答案 0 :(得分:2)
我认为你的术语令人困惑。也就是说,您将父类(一个角色)与基类混淆。
如果圆形是一个形状,那么当然通过创建一个圆形你也将创建一个形状,因为圆形是一个形状。这是不可避免的,完全正确的。但是形状不会成为一个额外的对象,它将被包含在圆圈中,这是它的一个组成部分。
你总是要引用父母的构造函数吗?
并非总是如此,如果您有一个默认构造函数,无论是没有参数还是参数默认值,您可以省略它并隐式获取默认构造函数。但由于Shape
只有一个带参数的构造函数,因此必须指定它。圆是一个形状,所以在你有一个圆之前,你必须有一个形状。
如果将构造函数更改为Shape::Shape(float base = 0.0, float height = 0.0)
,则可以从派生类的初始化列表中省略它。
父类与基类完全不同,父子关系与所有权有关,例如在确定性垃圾收集的情况下,当子元素的生命周期与父类的生命周期相关时。
答案 1 :(得分:0)
在我看来,您的代码存在问题,您只是对继承在C ++中的工作方式感到困惑。
每次从基类派生类时,在进入子类构造函数之前,如果没有参数,编译器会自动为您调用基类构造函数。例如,如果您的Shape类有像这样的构造函数
Shape::Shape(){ }
然后子类不必在初始化列表中调用基类构造函数(编译器会为您执行此操作)。现在你的构造函数看起来像这样:
Circle::Circle(float radius) {
this->radius = radius;
}
如果您没有没有参数的构造函数,则必须在初始化列表中显式调用它。
Circle 类型的每个对象都是一种形状,里面有更多信息。这并不意味着编译器创建两个对象只是因为它也初始化了父组件,你仍然有一个对象。
现在,如果你想让你的Circle与你的Shape对象不同,那么你就不再需要继承了。 (虽然我认为这不是你想要的)
你不能/不想避免调用基类构造函数,这是整个继承点:它允许你扩展一个对象的特征,它基于另一个对象&# 39;实施。