2016-07-21 15 views
1

これは古典的だと思いますが、私の場合は問題を単純化する制約があります。C++:派生クラスにダウンキャストしてオブジェクトを拡張する

私のモジュールの入力に構造体Aがいくつか追加されていて、それにいくつかの属性を追加したいだけです。だから私はAを拡張する構造体Bを作成し、必要なものを追加します。

私はBを期待しているメソッドを呼び出すが、それをAにすると、コンパイラは満足できない。すべてのネコ科のネコがライオンではないように、オブジェクトはBsではないかもしれない。

しかし、私の場合は、属性が少ないにもかかわらず、すべてがBだと誓っています。見つからない属性は、初期化されていないとして報告できます。それは問題ありません。また、初期化する前に属性を呼び出さないことを誓います。基本的には、Aオブジェクトを入力として取得するときに最初に行うのは、A属性に基づいて計算される残りのB属性を満たすことです。 Asの属性をメモリにコピーするので、いくつかの属性を追加するだけでBsのコピーを作成する必要はありません。私はAの元の属性を修正するつもりはありません。派生した属性を計算するためにそれらを使用し、A属性と派生した属性を持つBオブジェクトを回して処理します。

例:一般的な、プロジェクト全体のFromヘッダー

struct Rectangle { 
    // Side lengths 
    int a,b; 
} 

ローカルFromヘッダ:

struct LocalRectangle : Rectangle { 
    int area; 
} 

void updateModule(Rectangle inputRect); 

ローカルソースから:

私はどのように
void updateModule(Rectangle inputRect) { 
    LocalRectangle r = (LocalRectangle)inputRect; 
    r.area = r.a*r.b; 
    // More processing ... 
} 

これを行う ?事前に

おかげで、

チャールズ

+0

あなたはポストコードをお願いできますか? –

+0

多分、異なる属性を保持する 'std :: map'型のAs構造体にフィールドを追加し、A型のすべてであるBs構造体を削除することができます。 – LoPiTaL

+0

' A'を変更できますか? – Motti

答えて

1

あなたはあなただけ(ポインタまたはboost::optionalを使用して)初期化されていない値でAにこれらの値を追加することを検討して遅延し、それらを初期化することができA構造体を変更することができます。

そうでなければ、あなたがAを変更することはできません、あなたがBないを持つと考えることができB対応していますに各Aから値をコピーしたくない場合は、Aから派生するだけで追加の属性を持っています。次に、グローバルstd::map<A*, B>[1]を維持し、マップを参照して追加の属性を見つけます。このパスを選択する場合は、Aの廃止時期をmapから知るかどうかを尋ねてください。


  1. あなたがA Sのコピーを避けたいので、私はA*を使用しています。
1

Aが少数の属性を持つBであれば、それはBではありませんか?そうしないと、世界中のオブジェクトから他のオブジェクトにキャストでき、同じ名前/シグネチャを持つ属性/メソッドを探すことができます。

しかし、正しいタイプでないことがわかっているオブジェクトを渡す必要があるのはなぜですか?メソッドがBによって提供される余分な属性を必要としない場合は、B *ではなくA *をとるようにその署名を変更します。それらの値が必要な場合は、それらの値を持たないオブジェクトを渡すことはできません。

本当に本当にこれを行う必要があり、私はそれが良いデザインであるとは思わないと思うなら、恐らくAをとる静的な方法を考えて、不明な属性がnullまたは何かに設定されています。

関連する問題