双重推导 - 为什么需要施法

时间:2017-10-09 10:41:07

标签: c++ inheritance

以下代码包含几个定义了类的头文件: area, circle, ring, rectangle, patternarea是基类,圆是推导。 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两次的数据。但我不明白这个推理。

这是我尝试提供最少的代码,这只是标题:

“example0051.h”

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

#endif 

“example0052.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

“example0054.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

“example0055.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

1 个答案:

答案 0 :(得分:2)

注意您的层次结构如何:

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

因此,pattern *可以通过两种方式转换为area *。 编译器无法自行决定哪个版本更有效,因此会打印错误。

当添加到circle *时,很明显如何执行转换为area *

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