2012-01-19 5 views
4

私たちは数十年に渡って開発された大きなCコードベースを持っています。コードの特徴の1つは、関数ポインタと擬似継承に大きく依存することです。イディオムは、(hereを論じたように)ようなので、以下:Cで継承:良い、悪い、またはその他?

typedef struct twod_ { 
    double x, y; 
} twod; 

typedef struct threed_ { 
    twod super; 
    double z; 
} threed; 

threed *point_3d; 
twod *point_2d = (twod *)point3d; 

た時点point_2d->xpoint_3d->xは、メモリの同じブロックです。

私の質問は以下のとおりです。

  • このイディオムは、現代の生産コードではまだ普及していますか? (推奨されるオープンソースの例)
  • このコードでは、パフォーマンスの要件があります。このイディオムは速度やメモリの使用に役立ちますか?
  • これは実装された方法(または長年のコードが膨らんでいるため)では、スパゲッティコードのように感じるようになりました。これは実装やイディオムの問題ですか?別の言い方をすると、理想的な世界では、このイディオムを持つ500k LOCはすばやく理解できますか?もちろん

、格言、「それは壊したaintの場合は、それを修正していない」心に留めておくのは良いものであろう。しかし、それは現時点で私たちを助けてくれるわけではないので、リファクタリングでもっと深く考えなければならないと思っています。

ありがとう!

+0

"twod"変数を逆参照しようとすると、未定義の動作に終わってしまいますが、最後の行を 'twod * point_2d =&point3d.super; 'で置き換えると、水はうまくいきます。 –

+2

イディオムに関係なく、500k LOCがすぐに理解できるとは思わない –

+0

私はtwod * point_2d =(threed *)point3dだと思います。あなたは実際にtwod * point_2d =(twod *)point3dを意味しました。 – MetallicPriest

答えて

2

私はそれがかなり冗長になるので混乱するのはもちろん簡単ですが、それはいいと言いたいと思います。

私にとっては、「クラスを持つC」の主なオープンソース実装はおそらくGTK+であり、具体的にはgobjectモジュールです。

+0

もう少し言及する:GNOMEデスクトップ、GIMP(ofc GTK +あなたが言及したように!)、GStearmerはGObjectも使用する –

0

C言語のすべての機能に似ていますが、あなたが何をしているか分かっている限り、それは問題ありません。 しかし、問題が非常に簡単に表示されることがあります。たとえば、配列がthreedの場合、配列twodにキャストすることはできません。 (キャストされた配列のメンバーへのアクセスは未定義の振る舞いです)

1

でも問題はありませんが、コンパイラは可変アクセスやその他の問題に関連する問題については何も警告しませんそれ。このメソッドは型保護されていない場合があります。この明示的なキャストが悪い場合があるためです。この例を例に挙げてみましょう。

typedef struct _A 
{ 
    double x, y; 
} A; 

typedef struct _B 
{ 
    A super; 
    double z; 
} B; 

typedef struct _C 
{ 
    A super; // we wanted B, but wrote A by mistake 
    double w; 
} C; 

C* c; 
B* b = (B*)c; 

// will write to C::w instead of B::z and no one will warn you about this. 
// you'll need to track this by hand after your application crashes. 
b->z = 1234; 

このタイプのものは、地上に飛行機を置くことができます。 :)パフォーマンスについて

を、あなたは手(鋳造より安全な)によって、スーパーへのポインタを取るかのように、これは同じことをやってしまいます。

A* a; 
B* b = &a->b; 

また、私は、これは人気があるとは思いません最近では(最近のコンパイラでプログラミングをしてくれた私のような若いプログラマーにとっては少なくとも)

また、C++コンパイラはオプションですか?最近のコンパイラは最近、struct継承を可能にしています。

0

このイディオムは現代の生産コードではまだ普及していますか?( のオープンソースの例をお勧めします)

あなたはそれを今でも見ていますが、それはやや稀です。私はそれを人気と呼ぶわけではありません.Cプログラムの多型の使用はしばしば稀です。

このコードでは、パフォーマンスの要件があります。このイディオムは速度やメモリの使用に役立ちますか?

は、3つのメンバーすべてを含む構造体よりも効率的です。より効率的です。最悪の場合、遺産はコードの効率が悪くなります。最適な方法は、特定のプラットフォーム用のコンパイル出力に逆アセンブルして自分自身で確認することです。

...これは実装やイディオムに問題がありますか?

継承は一般的に慎重に使用する必要があります。それはすべてのOO言語に当てはまります。

個人的には、この特定のイディオムやCで軽度に役立つオブジェクト指向の機能を含めるという同様の試みは問題ではないかと思います。主に、プログラムにかなりの複雑さを加えるためです。このようなことは、 "ANSI-Cによるオブジェクト指向プログラミング"(Axel-Tobias Schreiner、90年代初めにリリース)という本で宣伝されました。私は個人的には、その本の中のほとんどのものがかなり恐ろしいと感じます。

理想的な世界では、このイディオムで500k LOCはすぐに理解されるでしょう ?

これは、この小さなオブジェクト指向のイディオムよりも、プログラムの構造、ファイル構造、コーディングの標準に大きく依存します。もちろん、プログラムが最先端であっても、500k locはすぐには理解されません。

関連する問題