2012-02-23 13 views
1

C++ 11で導入された新しいポインタテンプレートを使用して、配列の範囲を管理するきれいな方法を探しています。 win32 api関数を呼び出すとき。C++ 11で配列のシンプルなスコープを管理する最もクリーンな方法

もっと複雑な問題については議論がたくさんありますが、この比較的単純なシナリオは議論されていないようで、私が今始めているものよりも優れた選択肢があるのだろうかと思っています。

#include <memory> 

void Win32ApiFunction(void* arr, int*size) 
{ 
    if(arr==NULL) 
     *size = 10; 
    else 
    { 
     memset(arr,'x',10); 
     ((char*)arr)[9]='\0'; 
    } 
} 

void main(void) 
{ 
    // common to old and new 
    int size; 
    Win32ApiFunction(NULL,&size); 

    // old style - till now I have done this for scope reasons 
    if(char* data = new char[size]) 
    { 
     Win32ApiFunction(data,&size); 
     // other processing 
     delete [] data; 
    } 

    // new style - note additional braces to approximate 
    // the previous scope - is there a better equivalent to the above? 
    { 
     std::unique_ptr<char[]> data1(new char[size]); 
     if(data1) 
     { 
      Win32ApiFunction(data1.get(),&size); 
      // other processing 
     } 
    } 
} 
+5

どちらの場合も、newは割り当ての失敗に対して例外をスローし、0を返しません。 – karunski

+1

ほとんどの実際のWin32 API関数では、最初の呼び出しの前に "size"を0に初期化する必要があります。 – user9876

+1

2回目の呼び出しの前に配列を初期化する必要がある場合は、 'std :: vector 'が優れています(自動的かつ高速に実行されるため)。配列を0にする必要がなければ、不要なゼロ初期化を行うサイクルを費やさないので、 'std :: vector 'よりも優れています。また、最高のパフォーマンスが要求される状況にない場合は、どちらを使用するかは重要ではありません。 –

答えて

11

クリーンな方法は、あなたが必要とするすべてのへのポインタを渡すことで、(すなわち、それは、単一の連続ブロックとして保存されている)、それはCスタイルの配列と互換性があることも、C++ 98回の保証、std::vectorを使用することです最初の要素はWin32ApiFunctionです。 C++ 11では

std::vector<char> data(size); 
Win32ApiFunction(&data[0], &size); 

配列の先頭へのポインタを返す特殊なメンバ関数std::vector<T>::data()は(あなたが見る、ベクトル値型のoperator&()を過負荷にしてstd::addressofの使用について気にする必要はありませんがありますoperator&()のオーバーロードではC++ 98の問題ではHow can I reliably get an object's address when operator& is overloaded?が発行されます)。

+1

あなたはstd :: vector をここに入れたいと思います。 – karunski

+0

@karunski、ありがとう、ありがとう。 – Begemoth

+1

C++ 11の特別なメソッドがあることに注意してください:['std :: vector :: data'](http://en.cppreference.com/w/cpp/container/vector/data)ポインタを配列の先頭に返します。 – Xeo

関連する問題