2017-10-09 10 views
2

次のコードには、クラスが定義されているいくつかのヘッダーファイルが含まれています。 area, circle, ring, rectangle, patternareaは基本クラス、円は派生クラスです。 ringおよびrectangleは、circleの派生語であり、patternは、長方形の穴を含む色付き円の幾何学的図形を記述するcircleおよびrectangleの両方の派生語である。クラスareaは、colorの変数を定義します。これは、double derivationがpatternに2回含まれるためです。とにかく、私はあなたが一緒に従うことができる方法でこの質問を述べることができることを願っています!私は理解していないが第三最後の行のキャストが二重導出 - キャストが必要な理由

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_patterncircleのオブジェクトに変換する必要があるのはなぜですか。 これはプログラミング初心者の本の例です。そこには、オブジェクト patternareaのデータが2回含まれているため、キャストが必要であると記載されています。しかし、私はこの推論を理解していません。

"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 
+4

クラスとその継承階層の説明のみではなく、[最小、**完全**、および検証可能な例](http://stackoverflow.com/help/mcve)を作成してください。 –

+0

ヘッダー全体を投稿する必要はありません。しないでください。しかし、[mcve]を作成する必要があります。あなたの場合、これはおそらくすべてのクラスの定義だけを意味します**空のボディ**を持ちます。ちょうどそれがコンパイルしてあなたの問題を示しているように。 – bolov

+1

'blue_pattern'は本当に' circle'の子クラスですか?それではないかと思います。 – Bathsheba

答えて

2

ノートは、あなたの階層がどのように見えるか:

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

のでpattern *は、2つの方法でarea *にキャストすることができます。 コンパイラは、より有効なバージョンを自動的に判断することができないため、エラーが出力されます。

circle *にキャストすると、area *に変換する方法が明確になります。

おそらく次のステップでは、仮想継承とダイヤモンドの問題について学びますが、私の意見ではこの例はひどく、これは多重継承ではなく合成によって解決する必要があります。

+0

thx Marek、あなたは正しいでしょう、仮想継承は次に...ですので、 'blue_pattern'を' circle'にキャストすると、私のオブジェクトは 'circle'型になります。どちらのクラスでも 'calculateArea()'関数を定義しましたが、私はまだ円の部分ではなくパターンの面積を計算したいと思います。これは使えますか? –

関連する問題