0

構造体の動的配列をメンバー変数として別の構造体に格納したいと考えています。これは、メインの例でコンストラクターを使用する適切な方法ですか?

編集 コードにあった明らかな間違いのいくつかを修正しました(当時は午前6時でした)。また、B に別のメンバーを追加して、push_back がまだ正しいかどうかを確認しました。動的メモリのベクトルを使用すると、私の人生がずっと楽になることはわかっていますが、これらは最終的に推力::device_vector で使用される構造体であるため、この方法で行う必要があります。

struct A
{
    float mem1;
    int mem2;
};
struct B
{
    A * Aarr1;
    A * Aarr2;
    B(A * a1, A * a2): Aarr1(a1), Aarr2(a2){}
};
int main()
{
    A * test = new A[5];
    A * test2 = new A[10];
    vector<B> btest;
    btest.push_back(B(test, test2));
    for(int i=0; i<5; i++)
        printf("mem1: %f, mem2: %i \n", btest[0].Aarr[i].mem1, btest[0].Aarr[i].mem2);
}
4

3 に答える 3

1

のコンストラクタBはOKですが、呼び出す方法は次のpush_back()とおりではありません。

btest.push_back(B(A));

これを行う必要があります:

btest.push_back(B(test));

Bさらに、コンストラクターは次のようにマークされていないため、オブジェクトを明示的に構築する必要はありませんexplicit

btest.push_back(test);

また、生のポインターではなく自動メモリ管理を使用することを検討してください(std::vector<>配列の代わりに、ポインターの代わりにスマートポインター)。このようにして、これを忘れたためにメモリリークが発生するのを防ぐことができます。

delete test;

さておき、最悪のことは、初期化されていない変数(ループA内のメンバー変数)の値を使用するため、コードにも未定義動作があることです。for

最後に:、クラス定義でクラス名の後に使用しないでください。これは、C++11でコードを書き直す方法です。

#include <vector>
#include <cstdio>

struct A // Do not use ":" here, that's for introducing inheritance,
         // which you are not using in your example.
{
    float mem1 = 0.0; // In C++11, you can specify default initialization
    int mem2 = 0;     // for your member variables this way. In C++03 you
                      // would have to define a default constructor which
                      // initializes your member variables to the desired
                      // value.
};

struct B
{
    std::vector<A> Aarr;
//  ^^^^^^^^^^^^^^
//  Prefer using standard containers over dynamically allocated arrays, as
//  it saves your from taking care of memory management and avoids leaks.

    explicit B(size_t s): Aarr(s) { }
//  ^^^^^^^^
//  It is usually a good idea to mark constructors which take on argument
//  and are not copy constructors as explicit, to avoid awkward implicit
//  conversions.
};
int main()
{
    std::vector<B> btest;
    btest.push_back(B(5));
//                  ^^^^
//                  We need to explicitly construct an object of type B,
//                  because we have marked B's constructor as explicit.

    for(int i=0; i<5; i++)
    {
        std::printf(
             "mem1: %f, mem2: %i \n", 
            btest[0].Aarr[i].mem1, 
            btest[0].Aarr[i].mem2
            //                  ^
            //                  You had "mem1" here.
            );
    }
}
于 2013-03-16T10:11:45.703 に答える
1

単独で考えると、コンストラクターは問題ありません。ただし、コードには他にも多くの問題があります。

現状では、配列の割り当てが解除されないため、コードはメモリ リークを起こしています。

std::vectorまたはへの C 配列の使用をやめることを検討することをお勧めしますstd::array

printf()(スペルミス)にもバグがありますprint(): 2 つのうちの 1 つmem1mem2.

于 2013-03-16T10:09:01.120 に答える
0

コードに小さな間違いやタイプミスはほとんどありません。次のようになります。

struct A  // <-- no ':' after name type
{
    float mem1;
    int mem2;
};

struct B  // <-- no ':' after name type
{
    A * Aarr;
    B(A * a): Aarr(a){}
};

int main()
{
    A * test = new A[5];
    vector<B> btest;
    btest.push_back(B(test)); // <-- test, A is name of type
    for(int i=0; i<5; i++)
        printf("mem1: %f, mem2: %i \n", // <-- printf, not print
                btest[0].Aarr[i].mem1, btest[0].Aarr[i].mem1);
}

また、Cスタイルの配列の代わりにstd::vectorまたはを使用することも検討してください。std::array

于 2013-03-16T10:13:33.273 に答える