C++自定义复制构造函数详解
发布时间:2020-12-16 07:37:45 所属栏目:百科 来源:网络整理
导读:程序员可以定义一个类的复制构造函数。程序员定义的复制构造函数必须有一个形参,它是对同一个类的引用。 因此,在前面的例子中,复制构造函数的原型就应该是下面这个样子的: NumberArray :: NumberArray(NumberArrayobj) 此复制构造函数通过在复制之前为新
程序员可以定义一个类的复制构造函数。程序员定义的复制构造函数必须有一个形参,它是对同一个类的引用。 因此,在前面的例子中,复制构造函数的原型就应该是下面这个样子的: NumberArray :: NumberArray(NumberArray&obj) 此复制构造函数通过在复制之前为新对象的指针分配单独的内存来避免默认复制构造函数的问题:NumberArray :: NumberArray (NumberArray &obj) { arraySize = obj.arraySize; aPtr = new double[arraySize]; for(int index = 0; index < arraySize; index++) aPtr[index] = obj.aPtr[index]; }复制构造函数不应该改变被复制的对象,所以它将其实参声明为 const。下面的程序展示了修改 NumberArray 类以使用程序员定义的复制构造函数的方法。类声明在 NumberArray2.h 文件中,其成员函数的实现在 NumberArray2.cpp 中给出。 //NumberArray2.h 的内容 #include <iostream> using namespace std; class NumberArray { private: double *aPtr; int arraySize; public: NumberArray(NumberArray &); NumberArray(int size,double value); ~NumberArray() { if (arraySize > 0) delete [] aPtr;} void print() const; void.setValue(double value); }; //NumberArray2. cpp 的内容 #include <iostream> #include "NumberArray2.h" using namespace std; NumberArray::NumberArray(NumberArray &obj) { arraySize = obj.arraySize; aPtr = new double[arraySize]; for(int index = 0; index < arraySize; index++) aPtr[index] = obj.aPtr[index]; } NumberArray::NumberArray(int size,double value) { arraySize = size; aPtr = new double[arraySize]; setValue(value); } void NumberArray::setValue(double value) { for(int index = 0; index < arraySize; index++) aPtr[index] = value; } void NumberArray::print() const { for (int index = 0; index < arraySize; index++) cout << aPtr[index] << " "; } //main函数的内容 // This program demonstrates the use of copy constructors. #include <iostream> #include <iomanip> #include "NumberArray2.h" using namespace std; int main() { NumberArray first(3,10.5); //Make second a copy of first object NumberArray second = first; // Display the values of the two objects cout << setprecision(2) << fixed << showpoint; cout << "Value stored in first object is "; first.print(); cout << "nValue stored in second object is "; second.print(); cout << "nOnly the value in second object will " << "be changed.n"; //Now change value stored in second object second.setValue(20.5); // Display the values stored in the two objects cout << "Value stored in first object is "; first.print (); cout << endl << "Value stored in second object is "; second.print (); return 0; }程序输出结果:
Value stored in first object is 10.50 10.50 10.50 & 标识符引用形参将导致编译器错误。此外,形参应该是一个 const 引用,因为复制构造函数不应该修改被复制的对象。无论何时,只要在函数调用中按值传递对象,那么编译器就会自动调用复制构造函数,以创建对象的副本。正是出于这个原因,复制构造函数的形参必须按引用传递。因为,如果在构造函数被调用时按值传递,那么构造函数将立即被再次调用以创建按值传递的副本,从而导致对构造函数调用的无休止链条。 复制构造函数的调用每当创建一个对象,并使用同一个类的另一个对象来初始化它时,系统将自动调用复制构造函数,例如,以下每个初始化语句都将调用 Rectangle 类的复制构造函数:
Rectangle box(5,10);
void fun(Rectangle rect) fun(box); 这将导致 Rectangle 复制构造函数被调用。最后,只要函数通过值返回类的对象,就会自动调用复制构造函数。因此,在以下函数中,当 return 语句被执行时将调用复制构造函数:Rectangle makeRectangle() { Rectangle rect(12,3); return rect; }这是因为 return 语句必须为该对象创建一个临时的非局部副本,以便在函数返回之后,调用者可以使用该副本。总而言之,一个类的复制构造函数将在以下情况下被调用:
注意,当按引用或指针传递类的形参时,复制构造函数不会被调用。而且,当函数返回类对象的引用或指针时,也不会调用复制构造函数。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |