2016-09-21 43 views
1

私は、短い、簡潔な.c/.hファイルで定義された多数の別々のタイプのデータ(つまり、プロセス、ファイル、スレッド、関数など)を持っています。個々の部分の実装を終え、ユニット/コードカバレッジテストを終えたら、私は一緒に接続することに移りました。構造体へのポインタを持つ構造体:ベスト・アプローチ

現在の実装では、コード内のポインタ・ツー・parent- struct(void *)経由のポインタ、すなわち利用:私はいくつかのstruct sはどのように複雑に起因するvoid *のポインタを使用し、彼らはしません

struct typeB { 
    int B; 
    void *parent; 
}; 

struct typeC { 
    int C; 
    void *parent; 
}; 

struct typeA { 
    int a; 
    struct typeB *pB; 
    struct typeC *pC; 
}; 

void *の代わりに実際のpointer-to-struct-typeを使用するとコンパイルできます。

typeBtypeCはお互いに会話が必要な機能がいくつかありますが、まれです。また、structは、parentint aについて知る必要はありません。

私はparent structポインタを削除し、シンプルに自分の関数プロトタイプ/定義をリファクタリングすべてなど、サブ構造にアクセス、引数として(struct typeA *)を受け入れますが、いくつかの機能がちょうどtypeBにアクセスする必要があるとして、それは、やり過ぎと思われる可能性があり/ typeC構造とその要素。

(このサイトで頻繁に繰り返される "do not cast malloc()"ルールと同様の)構造体のこのような組織を扱うためのデファクト(非カーゴカルトプログラミング)標準がありますか?

ありがとうございます。

+1

フォワード宣言。それらを使用してください。 –

+0

@ n.m。けっこうだ。それを超えて、ポインタと親構造体のロジックを使用することに重大な懸念がありますか?ありがとうございました。 – DevNull

+0

継承を実装しようとしている場合は、オフセットが0になるように構造体の0番目の部分に親ポインタを配置してください。 –

答えて

2

私は何らかの構造体である、と私は* 、ボイドの代わりに、実際へのポインタ構造体型を使用する場合 は、彼らがコンパイルされませんどのように複雑にvoid *型のポインタを使用していました。

前方宣言で何が問題になりますか?あなたの質問のよう

struct typeA; // forward declaration 

struct typeB { 
    int B; 
    struct typeA *parent; 
}; 

struct typeC { 
    int C; 
    struct typeA *parent; 
}; 

struct typeA { 
    int a; 
    struct typeB *pB; 
    struct typeC *pC; 
}; 

:あなたは/が構造の一部として括弧格納する必要がしたくないなら、あなたは

a)は実際に、パラメータとして親アドレスを渡し、または

するか必要があります。

b)のような静的変数を定義し、子で動作するメソッドを呼び出す前に親構造体のアドレスを配置します。

最後の解決策はスレッドセーフではなく、エラーが発生しやすいです。

関連する問題