2016-05-20 2 views
1

I引数として二重ポインタを取る機能を有しています別の配列、例えば、特定のインデックス:スマートポインタ

double ** mat1 = new double*[2]; 
mat1[0] = new double[5]; 
mat1[1] = new double[5]; 
myFunction(mat1); 
... 
double **mat2 = new double*[2]; 
mat2[0] = &mat1[0][2]; 
mat2[1] = &mat1[1][4]; 
myFunction(mat2); 
... 
delete[] mat1[0]; 
delete[] mat1[1]; 
delete[] mat1; 
delete[] mat2; 

は、私はどちらか標準コンテナまたはスマートポインタで、メモリ管理を容易にするために、私のコード内のすべての「新しい」演算子を取り除くしたいと思います。しかし、関数の宣言を変更して、他の配列のサブセットを指す要素を持つ配列を作成して関数に渡すことはできません(スマートなポインタ型が必要ですポインタ)。

mat1はmat2と同じ型でなければなりません(両方とも関数のパラメータとして渡すことができます)。したがって、生ポインタのスマートポインタは使用できません。

これを行う方法はありますか?

編集: それは私が行うことができますようだ:

std::unique_ptr< std::unique_ptr<double[]>[] > mat2(new std::unique_ptr<double[]>[2]); 
mat2[0].reset(&mat1[0][2]); 
mat2[1].reset(&mat1[1][4]); 

が安全にそれをすることですか? mat2が破壊された場合、& mat1 [0] [2]と& mat1 [1] [4]の削除があると思われますか?

+0

なぜこれらの配列はすべて最初から動的に割り当てられていますか?なぜ単純な 'double [2] [5]'ではないのですか? – Quentin

+0

これは例ですが、サイズとインデックスは通常、実行時にのみ認識されます。 – seb007

+0

代わりに、関数はポインタのように使用できるもののコンテナを取ることができます。概念が出現するまでは、それを指定するのは難しいですが、通常のテンプレートパラメータは引き続き機能します。 – chris

答えて

1

IMHO、専用クラスで行列をカプセル化する必要があります。私は大体このようなことができクラスhierachyを使用します。

  • メモリがどこにあるかにかかわらず、アクセス関数が含まれており、それが
  • 割り当てるでしょう具体的な実装と割り当て解除メモリを得たかの共通の基底クラス
  • (あなたの例ではMAT2に使用する)

あなたがきれいに割り当て/割り当て解除の問題を分離し、それでもできる方法をマスター行列を表示するためにできるように具体的な実装を(あなたの例ではMAT1に使用します)透過的にac元の行列とそのビューに行きます。

具体的な実装は、その親のが破壊されていないこと(後者はもっと簡単です...)と、あなたの正確な要件が何であるかを表示する必要があるかどうかによって決まります共通アクセスの場合はビューの定義を参照してください。

+0

...動作しません。オーバーヘッドを減らすために、もっと基本的なことをしたいと思っていましたが、これが私の唯一の選択肢だと思います。テンプレートは私のコードを徐々に変換できるという利点がありました。 – seb007