这是我的泛型类Array,我想问一下复制构造函数和赋值,这是正确的方法吗?如果是,那么我真的需要在课堂上插入它们吗?
提前谢谢。
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];
}
}
答案 0 :(得分:4)
在这种情况下,您可以应用Rule of Zero:
template <class T, int SIZE>
class Array {
T data[SIZE];
public:
T& operator[](int index);
const T& operator[](int index) const;
};
编译器将为您生成函数。如果你需要在它们中做一些自定义的事情,那么是的,你需要定义它们。
在这种情况下,您的赋值运算符的签名需要修复(即您发布的代码不能编译):
template <class T,int SIZE>
Array<T,SIZE>& Array<T,SIZE>::operator=(const Array& a)
然后,您应该直接访问其他数组的data
,而不是使用其operator[]
(除非您有理由):
data[i] = a.data[i]; // note `a.data[i]` vs. `a[i]`
此外,您可以利用编译器来避免编写循环。只需将您的数组包装到struct
:
template <class T, int SIZE>
class Array {
struct S {
T data[SIZE];
} s;
// ...
};
这样你就可以用以下代码替换你的循环:
s = a.s;
不仅如此,但使用struct
将允许您复制构造数组的元素,而不是复制 - 分配它们(就像您使用循环一样),这对某些人来说可能很重要T
种类:
template <class T,int SIZE>
Array<T,SIZE>::Array(const Array& a)
: s(a.s) // note the member initializer
{
// empty body
}
答案 1 :(得分:0)
这解决了编译器错误:
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;
}
关于构造函数中数组元素的冗余初始化,还有一个单独的讨论。