Có một loại constructor đặc biệt nhằm sao chép một đối tượng vào một đối tượng khác. Constructor loại này có một tham số được tham chiếu đến một đối tượng khác của cùng class đó và được sử dụng để sao chép tất cả các dữ liệu quan trọng từ đối tượng nguồn sang đối tượng mới tạo ra (hoặc chính xác hơn đối tượng hiện đang được tạo ra).
Chúng được gọi là hàm khởi tạo sao chép (copying constructors) và được gọi một cách ngầm định khi khai báo của một đối tượng được theo sau bởi một trình khởi tạo (initiator). Nó cũng có thể được gọi nếu khai báo chỉ định một constructor phù hợp với khai báo.
Chữ “sao chép” không nên hiểu theo nghĩa đen. Các dữ liệu của đối tượng không thực sự cần phải được sao chép. Có thể nó chỉ thay đổi và được xử lý. Điều quan trọng là dữ liệu đó được lấy từ một đối tượng khác của cùng class. Với một class không có copying constructors và initiator được sử dụng trong quá trình khai báo đối tượng, nội dung của nó sẽ thực sự được sao chép “field by field” như kiểu nhân bản vô tính.
Lưu ý rằng các từ khoá const sử dụng trong khai báo tham số có thể xem như một lời hứa đảm bảo rằng các hàm đó sẽ không cố gắng để sửa đổi các giá trị được lưu trữ trong các đối tượng tham chiếu. Trình biên dịch sẽ cố gắng hết sức để giúp bạn giữ lời hứa đó.
Copying constructors cũng sẽ được sử dụng khi ngữ cảnh đòi hỏi một bản sao của một đối tượng cụ thể, ví dụ: khi một đối tượng cụ thể được truyền vào một hàm theo kiểu tham trị.
Ví dụ bên dưới cho thấy hai class khác nhau. Class1 có một copying constructor, trong khi Class2 thì không có. Hai đối tượng được tạo ra cho cả hai class trong khi cả hai đối tượng thứ hai được tạo ra bằng cách sao chép những đối tượng đầu tiên.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
#include <iostream> using namespace std; class Class1 { public: Class1(int val) { this -> value = val; } Class1(Class1 const &source) { value = source.value + 100; } int value; }; class Class2 { public: Class2(int val) { this -> value = val; } int value; }; int main(void) { Class1 object11(100), object12 = object11; Class2 object21(200), object22 = object21; cout << object12.value << endl; cout << object22.value << endl; return 0; } |
Chương trình sẽ in ra số 200 hai lần. Bạn hãy cố gắng tự mình giải thích điều này.