Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic Array with a generic size C++

Tags:

c++

this is my generic class Array, I would like to ask about the copy constructor and assignment, is this the right way to do it? If yes, then do I really need to insert both of them in the class?

Thank you in advance.

template <class T, int SIZE>
class Array {
    T data[SIZE];

public:
    explicit Array();
    Array(const Array& a); //copy constructor
    ~Array(); //destructor
    Array& operator=(const Array& a); //assignment
    T& operator[](int index);
    const T& operator[](int index) const;
};


template <class T,int SIZE>
Array<T,SIZE>::Array()
{
}

template <class T,int SIZE>
Array<T,SIZE>::~Array()
{

}

template <class T,int SIZE>
Array<T,SIZE>::Array& operator=(const Array& a)
{
    for(int i=0;i<SIZE;i++)
    {
        data[i]=a[i];
    }
    return *this;
}

template <class T,int SIZE>
Array<T,SIZE>::Array(const Array& a)
{
    for(int i=0;i<SIZE;i++)
    {
        data[i]=a[i];
    }
}
like image 1000
Sam12 Avatar asked Feb 20 '26 19:02

Sam12


1 Answers

In this case, you can apply the Rule of Zero:

template <class T, int SIZE>
class Array {
    T data[SIZE];

public:
    T& operator[](int index);
    const T& operator[](int index) const;
};

The compiler will generate the functions for you. If you need to do something custom in them, then yes, you need to define them.

In that case, the signature of your assignment operator needs to be fixed to (i.e. your posted code does not compile):

template <class T,int SIZE>
Array<T,SIZE>& Array<T,SIZE>::operator=(const Array& a)

Then, you should be directly accessing the other array's data, instead of using its operator[] (unless you have a reason):

data[i] = a.data[i]; // note `a.data[i]` vs. `a[i]`

Moreover, you can take advantage of the compiler to avoid writing loops. Simply wrap your array into a struct:

template <class T, int SIZE>
class Array {
    struct S {
        T data[SIZE];
    } s;

    // ...
};

So that you can replace your loops with:

s = a.s;

Not only that, but using the struct will allow you to copy-construct the elements of the array, rather than copy-assigning them (as you were doing with the loop), which may be important for some T types:

template <class T,int SIZE>
Array<T,SIZE>::Array(const Array& a)
: s(a.s) // note the member initializer
{
    // empty body
}
like image 190
Acorn Avatar answered Feb 23 '26 08:02

Acorn