Gobble up pudding

プログラミングの記事がメインのブログです。

MENU

誰得??配列の範囲外アクセスが起きないぐるぐる回る配列を作りました。

スポンサードリンク

f:id:fa11enprince:20200701021433j:plain
C++で演算子のオーバーロードを使ってたとえばa[5]の配列で
a[6]とかやると、a[0]を指すようにする謎配列を作りました。
PythonとかPerlの配列に似てるような感じのものですね。

単にオーバーロードの練習をしたかっただけという……

ソースコード

#include <iostream>
#include <iomanip>

template <typename T>
class Custom1DArray
{
public:
    Custom1DArray(int size)
        :size_(size)
    {
        arr_ = new T[size];    
    }

    // 代入演算子
    Custom1DArray& operator=(const Custom1DArray& rhs)
    {
        if (this != &rhs)
        {
            T *new_array = new T[rhs.size_];
            for (int i = 0; i < rhs.size_; i++)
            {
                new_array[i] = rhs.arr_[i];
            }
            // コンストラクタで確保した領域を消す
            delete [] arr_;
            arr_ = new_array;
            size_ = rhs.size_;
        }
        return *this;
    }
    ~Custom1DArray()
    {
        delete[] arr_;
    }
    // 添え字演算子 &を付けないと読み取り専用になる!
    int& operator[](int n)
    {
        int tmp = n % size_;
        if (tmp < 0)
        {
            tmp = size_ + tmp;
        }
        return arr_[tmp];
    } 
private:
    // たしかC++11からdeleteキーワードが使えるけどまあいいや
    Custom1DArray() {}  // 使用禁止
    Custom1DArray(const Custom1DArray&) {}  // 使用禁止
    T *arr_;
    int size_;
};

int main()
{
    Custom1DArray<int> c1(10);
    for (int i = 0; i < 10; i++)
    {
        c1[i] = i;
    } 

    for (int i = -10; i < 10; i++)
    {
        std::cout << std::setw(2) << c1[i] << " ";
    }
    std::cout << std::endl;
    Custom1DArray<int> c2(10);
    c2 = c1;
    c2[0] = 99;
    for (int i = 0; i < 20; i++)
    {
        std::cout << std::setw(2) << c2[i] << " ";
    }

    std::cout << std::endl;
}

実行結果

 0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5  6  7  8  9
99  1  2  3  4  5  6  7  8  9 99  1  2  3  4  5  6  7  8  9