当需要复制构造函数时,我有点不确定。例如,给定此功能:
template<class T>
T max(const T* array, int size) {
T result = array[0];
for (int i = 1; i < size; ++i) {
if (result < array[i]) {
result = array[i];
}
}
return result;
}
我需要T
类型的复制构造函数的原因是什么?我认为一定是因为我们以价值回报。此行T result = array[0];
是否还需要复制构造函数?
答案 0 :(得分:5)
我需要
copy constructor
类型T
的原因是什么?
T result = array[0];
这称为复制初始化,并调用类型T
的复制构造函数。类型T
将要求此行的复制构造函数成功。
我认为它必须是因为我们会返回一个值,因此
copy constructor
类型需要T
。
return result;
在大多数情况下,您的假设对于返回值是正确的。但是,在这种情况下,定义复制构造函数并不是必需的。要实现move semantics,您可以实现一个移动构造函数,它将不再需要复制构造函数,因为局部变量result
将被移动&#34;而不是&#34;复制&#34;从。移动语义从函数返回时不需要大型对象的不必要副本,因为在函数返回后将无法访问这些大对象。
答案 1 :(得分:1)
这已在这里得到解答:
What's the difference between assignment operator and copy constructor?
所以问题是:
复制构造函数用于从其他对象的数据初始化以前未初始化的对象。
赋值运算符用于将先前初始化的对象的数据替换为其他对象的数据。
以下是一个例子:
#include <iostream>
using namespace std;
class MyClass{
public:
MyClass(){
cout << "Default ctor\n";
}
MyClass(const MyClass& copyArg){
cout << "Copy ctor\n";
}
MyClass(MyClass&& moveArg){
cout << "Move ctor\n";
}
void operator=(const MyClass& assignArg){
cout << "Assignment operator\n";
}
bool operator<(const MyClass& comparsionArg) const {
return true;
}
};
template<class T>
T max(const T* array, int size) {
T result = array[0];
for (int i = 0; i < size; ++i) {
if (result < array[i]) {
result = array[i];
}
}
return result;
}
int main(){
MyClass arr[1];
const MyClass& a = max(arr, 1);
return 0;
}
要了解到底发生了什么we need to compile with -fno-elide-constructors
。
输出结果为:
Default ctor
Copy ctor
Assignment operator
Move ctor
所以在这里,对于一个数组元素,在此行调用默认构造函数:
MyClass arr[1];
然后我们初始化一个以前未初始化的对象,并调用复制构造函数:
T result = array[0];
然后我们对以前初始化的对象和赋值运算符进行了分配:
result = array[i];
在我们需要在函数范围之外创建对象之后,因为我们按值返回并且为移动构造函数调用:
return result;
然后将main
范围内用移动构造函数构造的对象绑定到const引用:
const MyClass& a = max(arr, 1);