双重派生 - 为什么需要铸造

Double derivation - why cast is necessary

本文关键字:为什么 派生      更新时间:2023-10-16

以下代码包含多个在其中定义类的头文件:area, circle, ring, rectangle, pattern.area是基础类,圆是推导。ringrectanglecircle的推导,patterncirclerectangle的推导,描述了一个彩色圆的几何图形,其中包含一个矩形的孔。类area定义了一个变量color由于双重派生,该变量将包含在pattern两次中。无论如何,我希望我能以一种你可以遵循的方式陈述这个问题!

请考虑以下代码:

int main() {
area *list[8];
ring blue_ring("BLUE",5,2);
pattern blue_pattern("BLUE",30,5,5);
list[0]=&blue_ring;
list[4]=static_cast<circle *>(&blue_pattern);
return 0;
}

我不明白的是倒数第三行的演员阵容。对象blue_pattern的类型为pattern。指针数组list存储指向area类型的对象的地址。那么为什么我必须blue_pattern转换为circle类型的对象。 这是一本编程初学者书中的示例。它在那里说强制转换是必要的,因为对象pattern包含来自area两次的数据。但我不明白这个推理。

这是我试图提供最少的代码,这只是标头:

"例子0051.h"

#ifndef _AREA_
#define _AREA_
class area {
public: 
area(char * n);
~area();
void getColor() const;
private: 
char color[11];
};
#endif 

"例子0052.h"

#ifndef _CIRCLE_
#define _CIRCLE_
#include "example0051.h"
class circle : public area {
public: 
circle(char * n, float a);
~circle();
float calculateArea() const;
private: 
float radius;
};
#endif

"例子0054.h">

#ifndef _RECTANGLE_
#define _RECTANGLE_
#include "example0051.h"
class rectangle : public area {
public: 
rectangle(char * n, float a, float b);
~rectangle();
float calculateArea() const;
private:
float length;
float width;
};
#endif

"例子0055.h">

#ifndef _PATTERN_
#define _PATTERN_
#include "example0052.h"  // circle
#include "example0054.h" // rectangle
class pattern : public circle, public rectangle {
public: pattern(char * n, float a, float b, float c);
~pattern();
float calculateArea() const;
};
#endif

请注意层次结构的外观:

area        area
^           ^
|           |
|           |
rectangle    circle
^           ^
         /
       /
     /
pattern

因此,pattern *可以通过两种方式投射到area *。 编译器无法自行决定哪个版本更有效,因此它将打印错误。

添加转换为circle *时,很清楚如何执行转换为area *

可能在下一步中,您将了解虚拟继承和钻石问题,但在我看来,这个例子很糟糕,这应该通过组合来解决,而不是通过多重继承来解决。