-1

割り当てのコードに取り組んでいますが、ネストされたテンプレート型に問題があります。

3 要素配列の 3 要素配列 (int b[3][3] のようなもの) を作成するには、次のコードが必要です。

Array< Array<int> > b(3);

私のArray.hの関連部分は次のとおりです。

template <class T>
class Array{
    public:
    Array() : size(0){ data = NULL; }

    Array(int s) : size(s) { data = new T[size]; }

    Array(const Array & a) : size(a.length()) { 
       data = new T[a.length()];
       for(int i = 0; i < a.length(); ++i)
       data[i] = a[i];
    }

~Array(){ delete[] data; }  

T & operator[](int i) {
    if (i >= 0 && i < size){
        return data[i];
    } else {
        throw ArrayOutOfBounds(i);
    }
}

T operator[](int i) const{
    if (i >= 0 && i < size){
        return data[i];
    } else {
        throw ArrayOutOfBounds(i);
    }
}

Array<T> & operator=(const Array<T> &a){
    if(this == &a) return *this;
    delete[] data;
    data = new T[a.length()];
    for(int i = 0; i < a.length(); ++i)
        data[i] = a[i];
    size = a.length();
}

    int length() const { return size; }

    // Members

    private:
    int size;
    T * data;
}

6/1に完全なドライバー コードを更新します。

   // Test driver for generic Array object with assignment and bounds checking

   #include "Array.h"

int main() {
    Array<int> a1(10);
for (int i = 0; i < a1.length(); ++i)
        a1[i] = i * i;
Array<int> a2 = a1;
try {
    for (int i = 0; i <= a2.length(); ++i)
        cout << a2[i] << " ";
    cout << endl;
}
catch (const ArrayOutOfBounds & e) {
    cout << endl << "ArrayOutOfBounds index=" << e.index << endl;
}
Array< Array<int> > b(3);
for (int i = 0; i < b.length(); ++i) {
    for (int j = 0; j < b[i].length(); ++j)
        b[i][j] = i*b[i].length() + j;
}
for (int i = 0; i < b.length(); ++i) {
    cout << "b[" << i << "]= ";
    for (int j = 0; j < b[i].length(); ++j)
        cout << b[i][j] << " ";
    cout << endl;
}

Array<const char *> c(3);
c[0] = "moe"; c[1] = "curly"; c[2] = "larry";
Array<const char *> d(10);
d = c;
for (int i = 0; i < d.length(); ++i)
    cout << "d[" << i << "]=" << d[i] << " ";
cout << endl;

return 0;
}     

期待される出力:

0 1 4 9 16 25 36 49 64 81 
ArrayOutOfBounds index=10
b[0]= 0 1 2
b[1]= 3 4 5
b[2]= 6 7 8
d[0]=moe d[1]=curly d[2]=larry 

6/2更新

ギヨームの解決策に従って、私が使用したサイズ変更方法は次のとおりです。

Array<T> & resize(int newsize){
    delete[] data;
    data = new T[newsize];
    size = newsize;
    for(int i = 0; i < size; ++i)
        init(data[i], size);
}

再帰的なサイズ変更は、次のような高次元で機能します。Array< Array< Array<int> > > q(3);

4

1 に答える 1

2

貼り付けたコードに基づいて、これはクラッシュしないはずです。デストラクタを忘れましたか?メモリを削除するデストラクタが必要です。ある場合は、空の配列を削除するときにクラッシュしないように、データが nullptr (または NULL) に初期化されていることを確認する必要があります。

しかし、あなたのアプローチは混乱しています。配列のサイズは、実行時またはコンパイル時に決定されることになっていますか? int b[3][3]コンパイル時に決定されます。それが必要な場合は、サイズstd::arrayを C++11 のようにテンプレート引数にする必要があります。http://en.cppreference.com/w/cpp/container/arrayを参照してください。

実行時にサイズを決定する場合は、2 番目の次元のサイズを決定する resize メソッドが必要です。

編集:ドライバーコードに基づいて、コンストラクターで別のことを行う必要があります(Tが配列の場合、intをTに渡します)。正直なところ、これはほとんどバグのように思えます。この種の仕様により、コンストラクターが何をするかを説明するのが非常に難しくなります (Array を除くすべての型 T に対して既定の ctor を呼び出します)。

私はこのようなものをしたい:

private:
template <typename U>
void init(U&, int) {}

template <typename U>
void init(Array<U>& a, int sz)
{
    a.resize(sz);
}

public:
Array(int s) : size(s) {
    data = new T[size];
    for (int i = 0 ; i < size; ++i) {
        init(data[i], s);
    }
}

動作しますが、これは醜いです。C++11 を使用できる場合は、std::enable_if を使用してより良いものを使用できます

于 2013-06-01T19:29:11.733 に答える