1

演算子のオーバーロードと適切なクラスの作成などに関する知識をテストするために、safearray と呼ばれる独自のバージョンの配列を作成しようとしています。

2 つのエラーが発生しています。

SafeArray.h:11:15: エラー: 'const int SafeArray::operator' はオーバーロードできません

SafeArray.h:10:10: エラー: 'int& SafeArray::operator' で</p>

私のコードは 3 つのファイルに分割されています。

メイン.cpp

#include <cstdlib>
#include <iostream>

#include "SafeArray.h"

using namespace std;

int main(int argc, char** argv) {

    SafeArray a(10); // 10 integer elements

    for (int i = 0; i < a.length(); i++) {
        cout << i << " " << a[i] << "s" << endl; // values initialise to 0
    }

    cout << endl << a[1]; // Program exits here.

    a[3] = 42;
    cout << a[3];
    a[10] = 10;
    cout << a[10];
    a[-1] = -1; // out-of-bounds is "safe"?

    SafeArray b(20); // another array

    b = a; // array assignment

    for (int i = 0; i < b.length(); i++) {
        cout << b[i] << endl; // values copied from a
    }

    return 0;
}

SafeArray.h

#ifndef SAFEARRAY_H
#define SAFEARRAY_H

class SafeArray {
public:
    SafeArray(int);              // int variable will be the array size
    int length();
    int boundsCheck(int y);       // constructor will call this function
//    const SafeArray operator= (const SafeArray&);
    int& operator[] (int y);
    const int operator [] (const int y); // you need this one too.

    SafeArray &operator=(SafeArray rhs) { 
    std::swap(array, rhs.array);
    std::swap(length_, rhs.length_);
        }

    SafeArray(SafeArray const &other);
    ~SafeArray();
private:
    int length_;
    int *array;
    //int array[];
};

#endif  /* SAFEARRAY_H */

SafeArray.cpp

#include "SafeArray.h"
#include <iostream>

SafeArray::SafeArray(int x) {
    length_ = x;
    array = new int[length];
    for (int i = 0; i < length_; i++) {
        array[i] = 0;
    }
}

int SafeArray::length() {
    return this->length_;
}

int SafeArray::boundsCheck(int y) {

}

int& SafeArray::operator[] (int y) {
    return array[y];
}

SafeArray::~SafeArray() { 
    delete [] array;
}

SafeArray::SafeArray(SafeArray const &other) { 
    int *temp = new int[rhs.size_];
    for (int i=0; i<rhs.size_; i++)
        temp[i] = rhs.array[i];
    std::swap(temp, array);
    delete [] temp;
    return *this;
}
4

4 に答える 4

3

クラス定義が無効です。int array[]は不完全な型であり、(非静的)クラスメンバーとして表示されてはなりません。一部のコンパイラはこれをの同義語として受け入れint array[0]ますが、ゼロサイズの配列はC ++でも無効です(C99のみ)。

つまり、自分のやり方でコードを書くことはできません。動的割り当てについて学び、自分のメモリを管理する必要があります。std::vector実装方法を確認してください。

C ++ 11ではstd::unique_ptr<int[]> array、クイックフィックスアプローチとして、として初期化することをお勧めしarray(new int[x])ます。

于 2012-04-03T23:43:36.697 に答える
0

@Kerrekがすでに指摘しているように、クラス定義は明らかに間違っています(コンパイルしないでください)。

これを修正するには、定義を次のように変更します。

int *array;

次に、デフォルトのコンストラクターで次のようなものを使用できます。

SafeArray::SafeArray(unsigned size = 0) 
    : array(new int[size])
{ 
    for (unsigned i=0; i<size; i++)
        array[i] = 0;
}

次に、はい、代入演算子を作成する必要があります。通常の方法は、コピーとスワップのイディオムと呼ばれます。コピーを作成してから、現在のコンテンツをコピーのコンテンツと交換します。

SafeArray &operator=(SafeArray rhs) { 
    std::swap(array, rhs.array);
    std::swap(length_, rhs.length_);
}

それに加えて、データのコピーも作成するコピーコンストラクターが必要になります。

SafeArray::SafeArray(SafeArray const &other) { 
    int *temp = new int[rhs.size_];
    for (int i=0; i<rhs.size_; i++)
        temp[i] = rhs.array[i];
    std::swap(temp, array);
    delete [] temp;
    return *this;
}

最後に、オブジェクトを破棄し、(特に)オブジェクトが保持しているメモリを削除するには、デストラクタが必要です。

SafeArray::~SafeArray() { 
    delete [] array;
}

次に、そのすべてが醜い混乱であり、実際にはうまく機能しないことを理解してください。特に、基本的な方法は、基本的にサイズが固定されているアレイに制限されています。sのみを格納する限りint、問題を見逃し、(ある種の)機能する動的配列を作成するのはかなり簡単です。ただし、他のタイプを格納する場合は、メモリの割り当てとそのメモリ内のオブジェクトの初期化を分離する必要があります。つまり、上記のすべてのコードを破棄し、次のようなものに置き換える必要があります。

  1. アレイサイズと割り当てサイズを別々に追跡します
  2. ::operator new、アロケータオブジェクト、または同様のものでメモリを割り当てます
  3. new配置を使用して、必要に応じてメモリ内のオブジェクトを初期化します。
  4. 明示的なデストラクタ呼び出しを使用してオブジェクトを破棄します
  5. ::operator deleteメモリを解放するために使用します

等々。要約すると、それは些細な作業でstd::vectorはありません。

于 2012-04-04T00:05:27.497 に答える
0

実際には int array[] が有効で、クラス メンバーとして表示される場合があります。以下は、厳密な C++11 準拠でコンパイルされます。

class foo 
{
public:
    foo() {}
    int length;
    int A[];
};

void ralph()
{
    foo *bar = (foo *)new int[ 21 ];
    bar->length = 20;
    bar->A[0] = 1;
}

これは合法であり、利点があります (場合によっては)。一般的には使用されていませんが。

ただし、OPは次のよ​​うなものをもっと望んでいたと思います

class SafeArray {
public:
    SafeArray(int);              // int variable will be the array size
    int length();
    int boundsCheck(int y);       // constructor will call this function

    int& operator[] (int y);
    const int operator [] (const int y) // you need this one too.
private:
    int length_;
    int *array;
};

一緒に

SafeArray::SafeArray(int x) {
    length_ = x;
    array = new int[length];
    for (int i = 0; i < length_; i++) {
        array[i] = 0;
    }
}
于 2012-04-04T00:04:49.407 に答える
0

エラー メッセージは、次の 2 行を参照しています。

int& operator[] (int y);
const int operator [] (const int y); // you need this one too.

あなたのエラーメッセージは、 (int y) と (const int y) が似すぎて [] 演算子の 2 つの異なるオーバーロードではないことを示しています。(int y) と (const int y) をオーバーロードすることはできません。これは、呼び出しがすべてあいまいになるためです。

SafeArray が const の場合は const int を返すつもりでしたが、SafeArray が const でない場合は int& を返すつもりでした。その場合、const SafeArray に適用する 2 番目の関数を宣言するには、パラメータ リストの後に const という語を置きます。SafeArray.h に次のように記述します。

int& operator[] (int y);
const int operator [] (int y) const; // you need this one too.

次に、これらの関数を両方とも SafeArray.cpp に記述する必要があります。

int& SafeArray::operator[] (int y) {
    return array[y];
}

const int SafeArray::operator[] (int y) const { // you need this one too.
    return array[y];
}
于 2014-11-14T22:37:38.667 に答える