web-dev-qa-db-ja.com

ポインターのC ++配列

C++で、ポインターの配列が必要な場合は、後の段階で異なるオブジェクトを指すようにして、構文がどのようになるかを確認します。

編集

私が推測していることを明確にする必要があります。メソッドを持つクラスfooがあり、メソッドを追加します。 addメソッドでは、クラスバーへの参照を取得します。その参照をbarのポインター配列に保存したい。ポインターバーの配列は、これに問題がない限り常に拡張する必要があります。ポインターのヒープ上に作成して配列するので、後でバーオブジェクトを割り当てることができます。クラスバーには、コンパイラが不満を言っているデフォルトのコンストラクタがないため、私が試したことは失敗したようです。これは、私がやりたくない実際のオブジェクトの配列を作成していたと思うようになりました。

Stlとnoをお願いします。これがあなたの意見であるなど、これがおかしいと思う方法について聞きたくありません。

22
Thomas

あなたが欲しいのは:

_Foo *array[10]; // array of 10 Foo pointers
_

混同しないでください:

_Foo (*array)[10]; // pointer to array of 10 Foos
_

いずれの場合も、これらはまだ(たとえば、新しいものに)割り当てられていないFoosへのポインタを表すため、何も自動的に初期化されません。

基本型にアクセスする方法を記述していることに気づいたとき、私はついにCでポインター/配列宣言構文を「取得」しました。 _Foo *array[5][10];_は、_*array[0..4][0..9]_(5項目の配列の添え字、10項目の配列の添え字、ポインターとしての逆参照)がFooオブジェクトにアクセスすることを意味します(_[]_は_*_)より高い優先順位。

これは逆に思えます。 _int array[5][10];_(別名int (array[5])[10];)は10個の_int array[5]_の配列であると考えるでしょう。これが事実だとします。次に、_array[9][4]_と言って、配列の最後の要素にアクセスします。それも後方に見えませんか? Cの配列宣言は、(予想されるような配列式の構成ではなく)基本型に到達する方法を示すパターンであるため、配列宣言と配列を使用するコードをフリップフロップする必要はありません。

52
Joey Adams

たとえば、intポインターの配列が必要な場合は、int* a[10]。これは、変数aが10 int* s。

[〜#〜] edit [〜#〜]

私はこれがあなたがしたいことだと思います:

class Bar
{
};

class Foo
{
public:

    //Takes number of bar elements in the pointer array
    Foo(int size_in);

    ~Foo();
    void add(Bar& bar);
private:

    //Pointer to bar array
    Bar** m_pBarArr;

    //Current fee bar index
    int m_index;
};

Foo::Foo(int size_in) : m_index(0)
{
    //Allocate memory for the array of bar pointers
    m_pBarArr = new Bar*[size_in];
}

Foo::~Foo()
{
    //Notice delete[] and not delete
    delete[] m_pBarArr;
    m_pBarArr = NULL;
}

void Foo::add(Bar &bar)
{
    //Store the pointer into the array. 
    //This is dangerous, you are assuming that bar object
    //is valid even when you try to use it
    m_pBarArr[m_index++] = &bar;
}
7
Naveen

私はこれらの線に沿って何かをするでしょう:

class Foo{
...
};

int main(){
  Foo* arrayOfFoo[100]; //[1]

  arrayOfFoo[0] = new Foo; //[2]
}

[1]これにより、Fooオブジェクトへの100個のポインターの配列が作成されます。しかし、実際にはFooオブジェクトは作成されません。

[2]これは、オブジェクトをインスタンス化すると同時に、このオブジェクトへのポインターを配列の最初の位置に保存する1つの方法です。

3
triktae

STLを使用しない場合、コードは たくさん Cのようなビット.

#include <cstdlib>
#include <new>

template< class T >
void append_to_array( T *&arr, size_t &n, T const &obj ) {
    T *tmp = static_cast<T*>( std::realloc( arr, sizeof(T) * (n+1) ) );
    if ( tmp == NULL ) throw std::bad_alloc( __FUNCTION__ );
       // assign things now that there is no exception
    arr = tmp;
    new( &arr[ n ] ) T( obj ); // placement new
    ++ n;
}

Tは、ポインターを含む任意のPODタイプにすることができます。

arrは、new[]ではなく、mallocによって割り当てられる必要があることに注意してください。

3
Potatoswatter
2
ronag