2012-01-20 6 views
4

私はCの構造体をたくさん作成しているので、データをカプセル化してdllcインタフェースで渡すことができます。構造体には多くのメンバーがあり、デフォルトを持つようにして、少数のメンバーしか指定しないで作成することができます。C++でのC構造体の初期化

私が理解しているように、構造体はCスタイルのままでなければならないので、コンストラクタを含めることはできません。それらを作成する最良の方法は何ですか?私は工場を考えていたのですか?

+0

Yup;私にはいいですね。 –

答えて

3
struct Foo { 
    static Foo make_default(); 
}; 

工場は過剰です。指定されたインタフェースのインスタンスを作成するときに使用しますが、実装の実行時の型は作成サイトで静的には認識されません。

+6

これは確かに工場ですか?関数ではありますが、型ではありませんか? –

+0

私は上記のように、私は構造体がメソッドを含むことができず、依然としてcインタフェース上で使用されるとは考えていません。私は試したが、うまくいかなかった。 – dangerousdave

+2

@危険な掘り出し物:あなたが望むのは[POD](http://stackoverflow.com/questions/146452/what-are-pod-types-in-c)です。これらは '静的な 'メンバを持つことができます。 –

1

私は、コンストラクタクラスを使用します。

struct Foo { ... }; 
class MakeFoo 
{ 
    Foo x; 
public: 
    MakeFoo(<Required-Members>) 
    { 
    <Initalize Required Members in x> 
    <Initalize Members with default values in x> 
    } 

    MakeFoo& optionalMember1(T v) 
    { 
     x.optionalMember1 = v; 
    } 

    // .. for the rest option members; 

    operator Foo() const 
    { 
    return x; 
    } 
}; 

これは式の構造体の任意のセットメンバーにできます。

processFoo(MakeFoo(1,2,3).optionalMember3(5)); 
+0

有効な解決策ですが、私に尋ねると少し余計です。オブジェクトを構築するために複数のステートメントを持つのはどうしたのですか?連鎖は、使用時の労力を節約するものではなく、冗長コードを他の場所に追加するだけです。 – spraff

+1

@spraff、何も間違っていませんが、私は個人的にはexprression-orientedインターフェイスを好みます。中間値を保持する変数は必要ありません。 – Begemoth

1

私はここに、簡単なアイデアを持っているかである:

通常と同じように構造を作り、それを初期化する簡単な関数を作ります:

struct Foo{...}; 

void Default(Foo &obj) { 
    // ... do the initialization here 
} 

あなたが複数の構造を持っている場合、あなたは、あなたが「デフォルト」と呼ばれる多くの機能を持つことができますので、例えば、それぞれが独自のタイプを初期化し、関数をオーバーロードするためにC++で許可されています。

struct Foo { //... }; 
struct Bar { //... }; 

void Default(Foo &obj) {...} 
void Default(Bar &obj) {...} 

C++コンパイラパラメータに基づいて第1または第2のオーバーロードを呼び出すタイミングを知る。 &はobjにあなたが与えたパラメータを参照するので、objに対して加えられた変更は、あなたがパラメータとして渡した変数に反映されます。

編集: また、いくつかのパラメータを指定する方法もありますが、デフォルトのパラメータを使用して行うことができます。これは動作方法です:

たとえば、次のような関数です。次のようなパラメータのデフォルト値を指定できます。

void Default (Foo &obj, int number_of_something = 0, int some_other_param = 10) 
{ ... } 
+0

私はこのアプローチを時々使用します。パラメータを追加したり、オーバーロードを使用してさまざまなコンストラクタを作成することもできます。 –

+0

デフォルトパラメータは「新」とどのくらい正確ですか?彼らはいつも標準のC++で有効でしたが、私はそれ以前のかなり前から考えています。 –

+0

あなたは正しいです、私は最近彼らについて学びました、そして私は彼らが新しいと仮定しました。私はいくつかの研究を行い、今私は知っている:D – Tibi

3

C-Structsにはまだメンバー関数があります。ただし、仮想関数を使用し始めると、構造体のメモリのどこかに仮想テーブルが必要になるため、問題が発生します。通常のメンバ関数(コンストラクタなど)は実際に構造体にサイズを追加しません。その後、構造体を問題なくDLLに渡すことができます。

+0

@ dangerousdave:それが動作しない場合、私は壊れるコードがたくさんある。あなたはあなたの "実験"についてより多くの情報を与えることができますか?あなたはコンストラクタを持たない構造体とコンストラクタを持つ構造体に対して異なる "sizeof"の結果を得ますか? – Goz

+4

C++ 11では、標準レイアウト*クラス(コンストラクタやその他の非仮想メンバ関数を持つことができる)のままであるため、問題ありません。 C++ 03では、実際にはうまくいくかもしれませんが、コンストラクタを追加するとレイアウトが維持されるという保証はありません。 –

+0

@Mike Seymour:十分に公正で、それまで聞いたことがない(またはさらに経験した)。その問題を指す仕様の特定の部分を教えてください。 – Goz

関連する問題