Hàm Tạo Sao Chép (Copy Constructor) : Định Nghĩa , Cách Thức Hoạt ...
Có thể bạn quan tâm
Lập trình
Thứ Sáu, 13 tháng 6, 2014
Hàm tạo sao chép (Copy Constructor) : Định nghĩa , cách thức hoạt động cơ bản
Trong luc lập trình với lớp rất nhiều khi ta cần tạo một đối tượng mới có dữ liệu giống với những đối tượng đã được thành lập từ trước , để giải quyết vấn đề này c++ có cách thức : Hàm tạo sao chép (Copy Constructor) Ta đã có những cách khai báo đối tượng như sau : Ten_class dt1,dt2; TenClass * p = new TenClass; Và đây là cách khai báo đối tượng theo kiểu Hàm tạo sao chép (Copy Constructor) : TenClass dt3; // Tạo đối tượng dt3. TenClass dt4(dt3); // Tạo dt4 theo dt3 Khi gặp dòng trên chương trình tạo ra một đối tượng dt4 ,cấp phát bộ nhớ cho nó kiểu TenClass và sao chép toàn bộ dữ liệu(từng bit) của dt3 vào dt4 , người ta gọi đó là hàm tạo sao chép mặc định . Ta thấy trong đa số các trường hợp (không có con trỏ và tham chiếu ) thì chỉ cần hàm sao chép mặc định là đủ . Nhưng thực tế có rất nhiều những trường hợp có dữ liệu kiểu con trỏ (mảng,cấp phát động,...) ,tham chiếu thì ta không thể dùng cách này (trường hợp này nói sau) . Cách xây dựng hàm tạo sao chép: Hàm tạo sao chép sử dụng đối kiểu tham chiếu để khởi gán cho đối tượng mới : Ten_class(Ten_class & dt1){ ...... // Những lệnh làm việc với thuộc tính dt1 để tạo đối tượng mới. } Ta thấy khi không có con trỏ và tham chiếu chỉ cần hàm mặc định là đủ (không cần khai báo) chỉ cần : TenClass dt1(dt); //dt đã được làm việc qua. Nhưng khi thuộc tính có kiểu con trỏ , nếu ta dùng hàm mặc định khi đó 2 thuộc tính con trỏ của 2 đối tượng trên sẽ cùng trỏ tới một ô nhớ khi đó nếu thay đổi con trỏ của đối tượng này thì con trỏ của đối tượng kia sẽ thay đổi , thậm chí khi ta xóa (delete) vùng nhớ của con trỏ này thì cũng đồng nghĩa con trỏ kia cũng bị xóa (NULL) Như vậy chỉ dùng hàm tạo sao chép mặc định thôi là chưa đủ . Ta cùng đến với một vài ví dụ :Kết Quả :// Hàm tao sao chép#include<iostream>#include<string.h>using namespace std;class SinhVien{private :int tuoi;char* ten;int len;// do dai tenpublic :void setname(char name[]){strcpy(ten,name);}char * getname(){return ten;}void settuoi(int tuoi){this->tuoi = tuoi;}int gettuoi(){return tuoi;}//Ham taoSinhVien(int len){this->len = len;ten = new char[len+1];//nen luon de dong cap phat bo nho nay// trong ham khoi tao}//ham tao sao chepSinhVien(SinhVien & dt){this->len = dt.len;this->ten = new char[dt.len+1]; // Phai cap phat bo nho truocthis->tuoi = dt.tuoi;//thuoc tinh tuoi cua doi tuong dang duoc khai bao// se co thuoc tinh tuoi giong thuoc tinh tuoi cua dt;for(int i=0 ;i<len;i++){(*this).ten[i] = dt.ten[i];}}void show();// Xuat thong tin cua sinh vien};void SinhVien :: show(){cout << "Ten la: " << ten << endl;cout << "Tuoi la: " << tuoi << endl;}int main(){//cout << "Do dai cua ho ten la: ";//int len;//cin >> len;char ten[] = "Nguyen Van a";SinhVien sv(strlen(ten));sv.setname(ten);sv.settuoi(17);cout << "Thong tin cua sinh vien thu nhat: " << endl;sv.show();SinhVien sv2(sv); // tim den ham tao copy co doi truyen vao.cout << "Thong tin cua sinh vien thu hai : " << endl;sv2.show();return 0;}
Ở đây 2 con trỏ của 2 đôi tượng không trỏ cùng vào một vùng nhớ vì thế các bạn có thể delete[] thuộc tính tên của đối tượng bất kì và kiểm tra đối tượng còn lạiVí dụ ở đây tôi thêm hamhuy(tôi chỉ ví dụ thôi chứ đây không phải hàm hủy thực sự.) :void hamhuy(){ delete[] ten; }
Thêm vào trong class SinhVien (public) .Sau đó code lại :
// Hàm tao sao chép
#include<iostream>
#include<string.h>
using namespace std;
class SinhVien{
private :
int tuoi;
char* ten;
int len;// do dai ten
public :
void setname(char name[]){
strcpy(ten,name);
}
char * getname(){
return ten;
}
void settuoi(int tuoi){
this->tuoi = tuoi;
}
int gettuoi(){
return tuoi;
}
//Ham tao
SinhVien(int len){
this->len = len;
ten = new char[len+1];//nen luon de dong cap phat bo nho nay
// trong ham khoi tao
}
//ham tao sao chep
SinhVien(SinhVien & dt){
this->len = dt.len;
this->ten = new char[dt.len+1]; // Phai cap phat bo nho truoc
this->tuoi = dt.tuoi;//thuoc tinh tuoi cua doi tuong dang duoc khai bao
// se co thuoc tinh tuoi giong thuoc tinh tuoi cua dt;
for(int i=0 ;i<len;i++){
(*this).ten[i] = dt.ten[i];
}
}
void show();// Xuat thong tin cua sinh vien
void hamhuy(){
delete[] ten;
}
};
void SinhVien :: show(){
cout << "Ten la: " << ten << endl;
cout << "Tuoi la: " << tuoi << endl;
}
int main(){
//cout << "Do dai cua ho ten la: ";
//int len;
//cin >> len;
char ten[] = "Nguyen Van a";
SinhVien sv(strlen(ten));
sv.setname(ten);
sv.settuoi(17);
cout << "Thong tin cua sinh vien thu nhat: " << endl;
sv.show();
SinhVien sv2(sv); // tim den ham tao copy co doi truyen vao.
sv.hamhuy(); // Khong anh huong
cout << "Thong tin cua sinh vien thu hai : " << endl;
sv2.show();
return 0;
}
Nếu bạn muốn thấy vi dụ về việc hàm sao chép mặc định gây ra lỗi hai con trỏ vào cùng một vùng nhớ thì làm như sau :Bỏ cái hàm tạo sao chép do mình tạo nên tức là lúc này sử dụng hàm tạo mặc định của chương trình :
// Hàm tao sao chép
#include<iostream>
#include<string.h>
using namespace std;
class SinhVien{
private :
int tuoi;
char* ten;
int len;// do dai ten
public :
void setname(char name[]){
strcpy(ten,name);
}
char * getname(){
return ten;
}
void settuoi(int tuoi){
this->tuoi = tuoi;
}
int gettuoi(){
return tuoi;
}
//Ham tao
SinhVien(int len){
this->len = len;
ten = new char[len+1];//nen luon de dong cap phat bo nho nay
// trong ham khoi tao
}
//ham tao sao chep
/*SinhVien(SinhVien & dt){
this->len = dt.len;
this->ten = new char[dt.len+1]; // Phai cap phat bo nho truoc
this->tuoi = dt.tuoi;//thuoc tinh tuoi cua doi tuong dang duoc khai bao
// se co thuoc tinh tuoi giong thuoc tinh tuoi cua dt;
for(int i=0 ;i<len;i++){
(*this).ten[i] = dt.ten[i];
}
}*/
void show();// Xuat thong tin cua sinh vien
void hamhuy(){
delete[] ten;
}
};
void SinhVien :: show(){
cout << "Ten la: " << ten << endl;
cout << "Tuoi la: " << tuoi << endl;
}
int main(){
//cout << "Do dai cua ho ten la: ";
//int len;
//cin >> len;
char ten[] = "Nguyen Van a";
SinhVien sv(strlen(ten));
sv.setname(ten);
sv.settuoi(17);
cout << "Thong tin cua sinh vien thu nhat: " << endl;
sv.show();
SinhVien sv2(sv); // tim den ham tao copy co doi truyen vao.
sv.hamhuy(); // Khong anh huong
cout << "Thong tin cua sinh vien thu hai : " << endl;
sv2.show();
return 0;
}Kết quả :
Không có nhận xét nào:
Đăng nhận xét
Bài đăng Mới hơn Bài đăng Cũ hơn Trang chủ Đăng ký: Đăng Nhận xét (Atom)Bài đăng mới nhất
RAII (Resource Acquisition is Initialisation) - Cách thức quản lý tài nguyên trong C++
Bạn đã bao giờ gặp rắc rối trong việc quản lý tài nguyên trong C++, ví dụ như bộ nhớ ? Trong 1 project lớn nếu không quản lý bộ nhớ tốt sẽ...
Bài Viết
- ► 2017 (2)
- ► tháng 12 (1)
- ► tháng 1 (1)
- ► 2016 (8)
- ► tháng 10 (1)
- ► tháng 9 (1)
- ► tháng 3 (5)
- ► tháng 2 (1)
- ► 2015 (17)
- ► tháng 12 (10)
- ► tháng 11 (7)
Từ khóa » Hàm Khởi Tạo Sao Chép C++
-
Hàm Xây Dựng Sao Chép (Copy Constructor) Trong C++ - Freetuts
-
5.3.10 Hàm Khởi Tạo Sao Chép (Copying Constructors) - CppDeveloper
-
Copy Constructor Trong C++
-
Hàm Khởi Tạo Và Hàm Huỷ - Lập Trình Không Khó
-
Copy Constructor Trong C++
-
Hàm Tạo Sao Chép (copy Constructor) - VOER
-
Hàm Khởi Tạo (constructor) Trong C++
-
Copy String Trong C++
-
Hàm Thiết Lập Sao Chép - Giáo Trình Lập Trình Hướng đối Tượng - 123doc
-
Hàm Khởi Tạo (constructor) Và Hàm Hủy (destructor) Của Lớp Trong OOP
-
Sự Khác Biệt Giữa Trình Xây Dựng Sao Chép Và Toán Tử Gán Trong C ++
-
Sao Chép Hàm Tạo Trong C ++ - TutorialCup
-
[Tự Học C++] Constructors - Hàm Khởi Tạo Trong C++ »
-
Hàm Tạo (lập Trình Hướng đối Tượng) – Wikipedia Tiếng Việt