以下のコードでは、Classコンストラクターが呼び出されたときに、配列がサイズxの配列として定義されるようにしています。どうやってやるの?
class Class
{
public:
int array[];
Class(int x) : ??? { }
}
コンパイル時に計算できない非const次元の配列のサイズを初期化することはできません(少なくとも、現在のC++標準のAFAIKでは)。
配列の代わりにstd::vector<int>
を使用することをお勧めします。ほとんどの操作に配列のような構文を提供します。
皆さんはこれを非常に複雑にしています。もちろん、C++でこれを行うことができます。効率を上げるために、通常の配列を使用しても問題ありません。ベクトルは、配列の最終的なサイズが事前にわからない場合、つまり、時間とともに拡大する必要がある場合にのみ意味があります。
チェーンの1レベル上の配列サイズがわかっている場合は、動的割り当てもメモリリークの可能性もないため、テンプレートクラスが最も簡単です。
template < int ARRAY_LEN > // you can even set to a default value here of C++'11
class MyClass
{
int array[ARRAY_LEN]; // Don't need to alloc or dealloc in structure! Works like you imagine!
}
// Then you set the length of each object where you declare the object, e.g.
MyClass<1024> instance; // But only works for constant values, i.e. known to compiler
オブジェクトを宣言する場所で長さがわからない場合、または同じオブジェクトを異なる長さで再利用する場合、または不明な長さを受け入れる必要がある場合は、コンストラクターに割り当てて解放する必要があります。あなたのデストラクタ...(そして理論的には常にそれが機能したことを確認してください...)
class MyClass
{
int *array;
MyClass(int len) { array = calloc(sizeof(int), len); assert(array); }
~MyClass() { free(array); array = NULL; } // DON'T FORGET TO FREE UP SPACE!
}
新しい演算子を使用します。
class Class
{
int* array;
Class(int x) : array(new int[x]) {};
};
それができるとは思いません。少なくともあなたが望む方法ではありません。サイズが動的情報(x)に由来する場合、静的サイズの配列(array [])を作成することはできません。
ポインターへのポインターとサイズを保存し、コピーコンストラクター、代入演算子、デストラクターをオーバーロードして処理するか、std :: vectorを使用する必要があります。
class Class
{
::std::vector<int> array;
Class(int x) : array(x) { }
};
この古いスレッドを壊してごめんなさい。実際には、配列のコンパイル時のサイズを調べる方法があります。それはこのようなものになります:
#include <cstdlib>
template<typename T>
class Class
{
T* _Buffer;
public:
template<size_t SIZE>
Class(T (&static_array)[SIZE])
{
_Buffer = (T*)malloc(sizeof(T) * SIZE);
memcpy(_Buffer, static_array, sizeof(T) * SIZE);
}
~Class()
{
if(_Buffer)
{
free(_Buffer);
_Buffer = NULL;
}
}
};
int main()
{
int int_array[32];
Class<int> c = Class<int>(int_array);
return 0;
}
または、malloc/newが嫌いな場合は、代わりにサイズテンプレートクラスを作成できます。しかし、私はそれを本当にお勧めしませんし、構文は非常に醜いです。
#include <cstdio>
template<typename T, size_t SIZE>
class Class
{
private:
T _Array[sz];
public:
Class(T (&static_array)[SIZE])
{
memcpy(_Array, static_array, sizeof(T) * SIZE);
}
};
int main()
{
char int_array[32];
Class<char, sizeof(int_array)> c = Class<char, sizeof(int_array)>(int_array);
return 0;
}
とにかく、これがお役に立てば幸いです:)
ベクトルを使用する必要がないことを理解していません。配列を使用したい場合、効率の問題です。スペースが少ない、コピー時間が発生しない(このような場合、適切に処理されれば、デストラクタ内で配列を削除する必要すらありません)など、理由にかかわらず。
正解は:(引用)
class Class
{
int* array;
Class(int x) : array(new int[x]) {};
};
最適でない代替手段を強制的に使用させようとしないでください。そうしないと、経験の浅いプログラマーを混乱させてしまいます。
生の配列を使用する代わりに、ベクターを使用してみませんか。
class SomeType {
vector<int> v;
SomeType(size_t x): v(x) {}
};
ベクトルを使用すると、例外に直面した場合の自動リーク保護と、ローアレイに比べて他の多くの利点が得られます。
C++ではできません-代わりにstd :: vectorを使用してください:
#include <vector>
struct A {
std::vector <int> vec;
A( int size ) : vec( size ) {
}
};
私は同じ問題を抱えていて、このように解決しました
class example
{
int *array;
example (int size)
{
array = new int[size];
}
}
2つのオプション:
Std :: vectorを使用します。これにより、アレイのサイズを簡単に変更できます。
std :: tr1 :: arrayを使用します。これには静的なサイズがあります。
どちらもコンストラクタ初期化子リストで正しく初期化できます。