2015-08-14 54 views
0

我在C++中练习继承,我有一些构造函数问题。C++继承:子类实例同时使用子和父构造函数

当我创建的子类(圈子)的一个实例,它创建了两个孩子和家长的一个实例。还是呢?

我想只创建一个圆的实例,而不是形状和圆。

如果我删除:从圈的构造形状(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; 
} 

输出:

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

+3

那么问题是什么? – Slava

+1

如果你感到惊讶'Shape'的构造函数被调用,那么,你认为你在这里做什么:'Circle :: Circle(float radius):Shape(0.0,0.0)'? (一个派生类*(也)是一个父类,并且必须构建其本身的“父”部分,因此在其构造函数中调用其构造函数) – Caninonos

+0

因此,当从父类继承时,总是创建父类的实例孩子? – Spectrem

回答

0

这似乎对我没有你有你的代码有问题,你只是感到困惑继承用C如何工作++。

你从一个基类派生一个类,进入子类构造函数之前每次,编译器会自动调用基类的构造函数为你,如果它没有参数。例如,如果你的Shape类有过这样

Shape::Shape(){ } 

一个构造函数,则子类就不必调用初始化列表中基类构造函数(编译器会替你)。现在,您的构造函数可以是这样的:

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

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

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

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

你不能/不希望避免调用基类的构造函数,这是整个继承点:它允许你扩展一个对象的特性,它基于另一个对象的实现。

2

我认为你是混淆术语。也就是说,你将一个父母(一个角色)与一个基类搞混了。

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

Do you always have to reference parent's constructor?

并非总是如此,如果你有一个默认的构造函数,任何一个不带任何参数或参数的默认值,可以忽略它,并含蓄地得到默认的构造函数。但由于Shape只有一个构造函数需要参数,所以必须指定它。圆圈是一个形状,所以在你有圆圈之前,你必须有一个形状。

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

父东西从基类完全不同,亲子关系是关于所有权,例如在确定性垃圾收集的情况下,当孩子的一生被拴在父母的寿命。