ViVi Home > 技術文書 > ポインタ入門 > 動的配列クラス 演習問題


 

 

C/C++ ポインタ入門 > 動的配列クラス 演習問題
(C) by Nobuhide Tsuda
Jan-2014

演習問題

Vector は int 型データを要素として持つ動的配列クラスです。
operator[](ix), at(ix) で要素を参照でき、push_back(d), insert(ix, d), erase(ix) 等で要素を挿入、削除することが出来ます。 要素挿入時にデータ領域の容量が足りなくなると、データ領域が自動的に拡張されます。
上記以外にも、isEmpty(), size() などオブジェクトの状態を返すメンバ関数や、 resize(sz), reserve(sz) などでオブジェクトの状態を変えるメンバ関数を持ちます。
データタイプが int型固定の std::vector と概ね同一です。

Vector は要素を格納する領域を動的に確保し、m_data がそこを指します。
確保したデータ領域サイズは m_capacity に格納されます。
データ領域の頻繁な再確保を避けるために、領域は実際のサイズよりも余分に確保されます。
m_size にデータ領域に実際に格納されている要素数が格納されます。


要素が追加されデータ領域が足りなくなった場合、領域サイズは2倍されてメモリが確保され、 古い領域から新しい領域に要素がコピーされ、古い領域のメモリは解放されます。

  1. 下記のクラスを定義するコードを書き、ビルドしてみなさい。
  2. class Vector {
    private:
        int    *m_data;        // アロケートされたデータ領域へのポインタ
        int    m_size;           // データ領域に入っている要素数
        int    m_capacity;    // アロケートされたデータ領域サイズ
    };
    
  3. Vector クラスのオブジェクトを生成するコードを記述、ビルドし、デバッガでオブジェクトが生成されていることを確認しなさい。
  4. Vector クラスにコンストラクタ Vector() を追加し、メンバ変数を全て 0 に初期化するようにしなさい。
  5. コンストラクタ Vector() で、サイズを 0、キャパシティを 8 に設定し、m_data のための領域を new で確保しなさい。
  6. Vector クラスにデストラクタ ~Vector() を追加し、m_data を delete するようにしなさい。
  7. ★★ Vector クラスにサイズ指定コンストラクタ Vector(int sz, int d = 0) を追加し、 sz 個の要素を持った動的配列を構築可能にしなさい。要素の値は第2引数で指定するものとする。
  8. ★★ Vector クラスにデータ指定コンストラクタ Vector(const int *first, const int *last) を追加し、 初期化データを指定可能にしなさい。
  9. ★★ Vector クラスにコピーコンストラクタ Vector(const Vector &x) を追加し、 引数オブジェクト x の内容をコピーするようにしなさい。

  10. bool isEmpty() const Vector の要素が空かどうかを判定するメンバ関数を実装しなさい。
  11. int size() const Vector の要素数を返すメンバ関数を実装しなさい。
  12. int capacity() const Vector のアロケート済みデータ領域サイズを返すメンバ関数を実装しなさい。
  13. int front() const 配列の先頭要素を返すメンバ関数を実装しなさい。配列要素が空の場合は -1 を返しなさい
  14. int back() const 配列の末尾要素を返すメンバ関数を実装しなさい。配列要素が空の場合は -1 を返しなさい
  15. int at(int ix) const ix 番目の要素を返すメンバ関数を実装しなさい。ix が範囲外の場合は -1 を返しなさい。
  16. int operator[](int ix) const ix 番目の要素を返す [] 演算子をオーバロードしなさい。ix が範囲外の場合は -1 を返しなさい。

  17. void clear() 配列要素数(サイズ)をゼロにするメンバ関数を実装しなさい。
  18. ★★★void reserve(int sz) キャパシティが指定サイズ未満の場合は、指定サイズ以上になるようにデータ領域を拡張しなさい。 ただし、キャパシティは常に 2のべき乗の値(8, 16, 32, 64, ...)とする。
  19. ★★void resize(int sz) 配列サイズを指定サイズに設定するメンバ関数を実装しなさい。 増えた要素は初期化する必要は無い。sz がマイナスの場合は、サイズを 0 にしなさい。
  20. ★★void push_back(int d) 配列末尾に d を追加するメンバ関数を実装しなさい。
  21. ★★int pop_back() 配列末尾を削除し(サイズをデクリメント)、それを返すメンバ関数を実装しなさい。 配列要素が無い場合は、-1 を返しなさい
  22. ★★int &operator[](int ix) ix 番目の要素の参照を返す [] 演算子をオーバロードしなさい。ix の範囲チェックは行わなくてよい。
  23. ★★void swap(Vector &x) オブジェクトの内容全てを x と交換するメンバ関数を実装しなさい。
  24. ★★void insert(int ix, int d) ix の位置に要素 d を挿入するメンバ関数を実装しなさい。 ix < 0 の場合は先頭に、ix > size() の場合は末尾に挿入しなさい。
  25. ★★void erase(int ix) ix 位置の要素を削除し、それ以降のデータを前に移動するメンバ関数を実装しなさい。 ix < 0 または ix >= size() の場合は何も処理をしなくてよい。
  26. ★★void assign(int sz, int d) 配列を要素数 sz、全ての要素の値 d に初期化しなおしなさい。

 


前: |上:C/C++ ポインタ入門 |次: