4

JavaのArrayListに似たC++のテンプレートクラスに取り組んでいます(はい、ベクトルが同じことを行うことは知っています。これは実用的なコーディングプロジェクトではありません)。

別の ArrayList を引数として取り、ArrayList をシードする ArrayList クラスのコンストラクターがあれば便利だと思いました。しかし、コンストラクターを書き込もうとすると、このエラーが発生します

invalid constructor; you probably meant 'ArrayList<T> (const ArrayList<T>&)'

これは、ArrayList が定数でなければならないということですか? また、なぜ addressof 演算子が必要なのですか?

私はまだ C++ のロープを学んでいるので、少し混乱しています。

プロトタイプはここにあります:

    ArrayList(ArrayList<T> list);
    ArrayList(ArrayList<T> list, int size);

コードは次のとおりです。

/**
 * Creates an ArrayList of type T that is twice the
 * size of the passed in ArrayList, and adds all elements
 * from the passed ArrayList<T> list, to this ArrayList.
 *
 * Runs in O(n) time, where n = the size of list.
 *
 * @param list the ArrayList to use as a seed for this ArrayList.
 */
template<class T>
ArrayList<T>::ArrayList(ArrayList<T> list) {

    array = new T[list.getSize() * 2];
    capacity = list->getSize() * 2;
    size = list->getSize();

    for (int i = 0; i < list->getSize(); i++) {

        array[i] = list->get(i);
    }
}

編集 以下のコードではエラーが発生しませんが、上記のコードではエラーが発生します.....

/**
 * Creates an ArrayList of type T that has a capacity equal to the passed
 * in theCapacity parameter. This ArrayList starts with the passed ArrayList.
 *
 * Note: If the passed in capacity is smaller than the size of the passed in
 *          ArrayList, then the capacity is set to twice the size of the
 *          passed ArrayList.
 *
 * @param list the ArrayList to use as a seed for this ArrayList.
 * @param theCapacity the capacity for this ArrayList.
 */
template<class T>
ArrayList<T>::ArrayList(ArrayList<T> list, int theCapacity) {

    if (theCapacity >= list->getSize()) {

        array = new T[theCapacity];
        capacity = theCapacity;
    }
    else {

        array = new T[list->getSize() * 2];
        capacity = list->getSize() * 2;
    }

    size = list->size;

    for (int i = 0; i < size; i++) {

        array[i] = list->get(i);
    }
}
4

2 に答える 2

3

使用する

 ArrayList<T>::ArrayList(const ArrayList<T>& list)

配列リストを参照として渡すためのコンストラクター署名としてconst。これは、コピー コンストラクターの適切なシグネチャです。listctor 内で変更しない限り、実装と呼び出しコードの両方を変更する必要はありません。

これを行うArrayList<T>::ArrayList(ArrayList<T> list)と、ArrayList インスタンス全体の一時的なコピーが作成されます。( ctor に対してこれを行う必要はありません。新しいコピーがlist同じ関数定義などを使用するため、無限再帰が呼び出されるためです)。

ArrayList<T>::ArrayList(ArrayList<T>& list)リストを参照として渡します。つまり、「値渡し」と呼ばれることがなくなり、呼び出し元のコードからリストの正確なバージョンを処理します。

関数で const 参照を受け入れることにより、関数が参照の内容を変更しないことを意味します (つまり、変更操作を行わず、constアクセスのみに制限されます)。const先に進む前に、 、参照、およびコピー コンストラクターについて読む必要があります。

アップデート:

obj.member値渡しまたは参照渡しの場合、構文を介してメンバーにアクセスできます。のようなポインターを渡す場合は、構文または構文ArrayList<T>::ArrayList(ArrayList<T>* list)を使用する必要があり、リストが/最初であるかどうかを確認することは言うまでもありません (null ポインターを逆参照することはできません)。list->member(*list).member0nullptr

ポインターの構文と値/参照の構文が混在しています。ポインターを使用して引数を渡していないため、すべてをに変換list->xします。list.xlist

さまざまな通過動作については、こちらを参照してください: http://ideone.com/3c5mJ

于 2012-08-10T02:34:25.847 に答える
2

「const」は、変更しないオブジェクトの参照であるため使用されます。参照が使用されるのは、これがコピー コンストラクターであり、既定の構文が参照であることを前提としているためです。

しかし、最も重要なことは、このコンストラクターを、作成しようとしているものとまったく同じ方法で定義して使用できることです。

于 2012-08-10T02:41:18.847 に答える