1

私がこの構造体を持っているとしましょう:

    typedef struct Foo {
        int a;
        int b;
        int c;
    } Foo;

ここで、Foo にメモリを割り当てる初期化関数を作成し、次のように値をオブジェクトにプリセットします。

    void initializeFoo(Foo *foo) {
        foo = (Foo*)malloc(sizeof(Foo));
        foo->a=0;
        foo->b=15;
        foo->c=0;
    }

Foo の上に、Display という C++ クラスを作成したとしましょう。これにより、画面に Foo を表示できます。

     class Display {
          public:
              Display();

          private:
              Foo* foo;
     }

Display コンストラクター内で initializeFoo(foo) を使用して foo の値を初期化しますが、foo に設定したプリセット値がありません。

メモリ割り当ての問題である可能性があると思いました。Display が C++ の「new」で適切に割り当てられていることを確認しました。しかし、私は一日中頭を悩ませてきました。

機能しない唯一の理由は、initializeFoo() でこれらの値を設定したためだと思われます。しかし、それは私には意味がありません。

ここで何が起こっているのかについて、他の誰かがより良い意見を持っていますか?

4

3 に答える 3

3

あなたはおそらく意味した

void initializeFoo(Foo **foo) {
        *foo = (Foo*)malloc(sizeof(Foo));
        (*foo)->a=0;
        (*foo)->b=15;
        (*foo)->c=0;
    }
于 2013-03-07T07:49:45.500 に答える
2

ポインターも値で渡されます すべての出力パラメーターと同様に、アドレス ( &var) または C++ で渡す必要があります。パラメーターは参照型 (この場合はポインターへの参照型) にすることができます。最小の変更は言うまでもなく、後者の方が優れている可能性があります。

これを変える:

void initializeFoo(Foo *foo) 

これに:

void initializeFoo(Foo*& foo) // <== note reference-to-pointer

そうは言っても、これは、適切に定義されたRAII方法論を実践する優れた C++ プログラムには当てはまりません。そもそもリソースを所有するためのポインターを使用してはならない方法について、この簡単なドキュメントをお読みください。最終的にfooは、完全なオブジェクト インスタンスではないにしても、メンバーはスマート ポインターである必要があります。

于 2013-03-07T08:05:03.933 に答える
2

Fooポインターを値で渡しているinitializeFooため、呼び出し元のポインターを変更できません。このスタイルの初期化子が必要な場合は、ポインターにポインターを渡す必要があります。

void initializeFoo(Foo **foo) {
    *foo = malloc(sizeof(Foo));
    (*foo)->a=0;
    (*foo)->b=15;
    (*foo)->c=0;
}

ただし、この場合は、Foo*代わりに単純に返す方が簡単です。

Foo *initializeFoo() {
    Foo* foo = malloc(sizeof(Foo));
    foo->a=0;
    foo->b=15;
    foo->c=0;
    return foo;
}
于 2013-03-07T07:49:29.417 に答える