如何使用类实现多级继承

Posted

技术标签:

【中文标题】如何使用类实现多级继承【英文标题】:How to achieve Multilevel Inheritance with classes 【发布时间】:2018-10-18 02:46:49 【问题描述】:

我正在尝试从 Shape 类到 Rectangle、Circle 和 Triangle 类进行一些多级继承。从 Rectangle 我需要继承一个 Square 类并打印区域、信息等。以及来自 Circle 的 Ellipse 和来自 Triangle 的 Isosceles。到目前为止,我的第一个继承类工作正常,但每当我试图让“孙子”类工作时,我都无法让它工作。我不知道我可能做错了什么。代码如下:

 #include <iostream>
 using namespace std;

 class Shape
 protected:
 string name;
 float area;

 public:
 Shape(string nm):name(nm)

 //Getters
 string     getName()    return name;    
 float    getArea()

 //Setters
 virtual void    setArea()

 //Print
 virtual void printInfo()
 
    cout << "Name: " << name << " Color: " << endl;


;

class Rectangle :  public Shape
private:
float length, width;

public:
Rectangle(string nm, float l, float w):Shape::Shape(nm), length(l), width(w)
Shape::getName();

//Setters
void setArea() area = length*width; 

void printInfo()
    //Shape::printInfo();
    cout << "Name: " << name << " L: " << length << " W: " << width << " A: " << area << endl;

;

class Square : public Rectangle

private:
float length;

public:
Square(string nm, float l):length(l),Rectangle::Rectangle(nm)
float     getLength()return length;

//Setters
void setArea() area = length *length; 

;

class Circle : public Shape
private:
float radius;
const float pi = 3.0;

public:
Circle(string nm, float r):Shape::Shape(nm), radius(r)

//Setters
void setArea() area = pi*radius*radius; 

void printInfo()
    //Shape::printInfo();
    cout << "Name: " << name << " R: " << radius << " A: " << area <<      endl;

;

 //class Ellipse : public Circle
 //
 //private:
 //    float length, width, radius1, radius2;
   //
//public:
//    Ellipse(string nm, int clr, float l, float w);
//
//    //Setters
//void setArea() area = radius1 * radius2; 
//
//;

class Triangle : public Shape
private:
float a, base, c, height;

public:
Triangle(string nm, float a, float b, float c, float h):Shape::Shape(nm), a(a), base(b), c(c), height(h)

//Setters
void setArea() area = (base*height)/2; 

void printInfo()
    //Shape::printInfo();
    cout << "Name: " << name << " Color: " << " A: " << a << " Base: " << base <<  " C: " << c  << " H: " << height << " P: " << " A: " << area << endl;

;

//class Isosceles : public Triangle
//
//private:
//    float base, height;
//
//public:
//    Isosceles(string nm, int clr, float l, float w);
//
//    //Setters
//    void setArea() area = (base*height)/2; 
//
//; 

int main() 

Rectangle r("Rectangle", 10, 20);
Circle c("Circle", 1);
Triangle tt("Triangle", 2, 2, 3, 3);
Square ss("Square", 10);

Shape* s;
Shape* t;
Shape* u;
Shape* v;
s = &r;
t = &c;
u = &tt;
v = &ss;

//Set and print area of Rectangle
s->setArea();
s->printInfo();

//Set and print area of Circle
t->setArea();
t->printInfo();

//Set and print area of Triangle
u->setArea();
u->printInfo();

//Set and print area of Rectangle
v->setArea();
v->printInfo();


return 0;

在这里设置 Square 类时出错:

class Square : public Rectangle

private:
float length;

public:
Square(string nm, float l):length(l),Rectangle::Rectangle(nm)

我注释掉了 Ellipse 和 Isosceles 类,这样我就可以正确设置 Square 并且以后不再使用它们。 这是我第一次问问题,所以如果有什么不对的地方,请告诉我。 感谢您的帮助。

【问题讨论】:

应该有一些指示出了什么问题,否则,你怎么知道你有问题?编译程序时有错误吗?当你执行它时它不起作用,如果不是它有什么作用? “我在设置 Square 类时出错”是什么错误? 您很可能需要将Square(string nm, float l):length(l),Rectangle::Rectangle(nm) 更改为Square(string nm, float l): Rectangle(nm), length(l) 当然,Rectangle() 构造函数需要多个参数,所以这也不是答案... 在某些情况下,您的继承基于属性的数量(椭圆与圆形),而其他时间则基于 IS-A 关系(矩形与方形)。在实践中,两者都不好,最好还是使用单个级别(即与矩形处于同一级别的正方形)或仅保留更一般的形状(即矩形、椭圆和三角形)。 【参考方案1】:

在你的 Square 课上,我相信我发现了一个错误......

尝试使用方形构造函数执行以下操作:

Square(string nm, float l):length(l),Rectangle::Rectangle(nm, l, l) 

与您所拥有的相反...这将解决您在 Square 类中遇到的错误。

差异的原因是当您从 Square 构造函数向 Rectangle 构造函数传递参数时,您留下了一些未初始化的参数(在 Rectangle 构造函数中)。

【讨论】:

哇,我真的尝试了很多选择,除了这个。这给了我一些警告,但至少程序可以编译。非常感谢。

以上是关于如何使用类实现多级继承的主要内容,如果未能解决你的问题,请参考以下文章

Lombok @Builder 用于具有强制字段的多级继承中的类

实体框架+多级继承+EF代码优先

如何为多级组合类设计继承

CRTP 和多级继承

多级继承 C++

Php中使用mkdir如何创建多级目录?