Reputation: 1805
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];
}
}
Upvotes: 3
Views: 4616
Reputation: 26186
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
}
Upvotes: 4
Reputation: 69912
This solves the compiler error:
template <class T,int SIZE>
auto Array<T,SIZE>::operator=(const Array& a) -> Array&
{
for(int i=0;i<SIZE;i++)
{
data[i]=a[i];
}
return *this;
}
There is a separate discussion to be had about redundant initialisation of the array elements in the constructor.
Upvotes: 0