a. Hàm t o sao chép m c đ nhạ ặ ị
Gi s đã đ nh nghĩa m t l p nào đó, ví d l p ả ử ị ộ ớ ụ ớ PS (phân s ). Khi đó:ố
+ Ta có th dùng câu l nh khai báo ho c c p phát b nh đ t o các đ iể ệ ặ ấ ộ ớ ể ạ ố tượng m i, ví d :ớ ụ
PS p1, p2 ; PS *p = new PS ;
+ Ta cũng có th dùng l nh khai báo đ t o m t đ i tể ệ ể ạ ộ ố ượng m i t m t đ iớ ừ ộ ố tượng đã t n t i, ví d :ồ ạ ụ
PS u;
PS v(u) ; // T o v theo u ạ ý nghĩa c a câu l nh này nh sau:ủ ệ ư
− N u trong l p ế ớ PS ch a xây d ng hàm t o sao chép, thì câu l nh này sư ự ạ ệ ẽ g i t i m t hàm t o sao chép m c đ nh (c a C++). Hàm này s sao chépọ ớ ộ ạ ặ ị ủ ẽ n i dung t ng bit c a u vào các bit tộ ừ ủ ương ng c a v. Nh v y các vùngứ ủ ư ậ nh c a u và v s có n i dung nh nhau. Rõ ràng trong đa s các trớ ủ ẽ ộ ư ố ường h p, n u l p không có các thu c tính ki u con tr hay tham chi u, thì vi cợ ế ớ ộ ể ỏ ế ệ dùng các hàm t o sao chép m c đ nh (đ t o ạ ặ ị ể ạ ra m t đ i tộ ố ượng m i có n iớ ộ dung nh m t đ i tư ộ ố ượng cho trước) là đ và không c n xây d ng m tủ ầ ự ộ hàm t o sao chép m i.ạ ớ
l nh:ệ PS v(u); s t o ra đ i tẽ ạ ố ượng m i v, sau đó g i t i hàm t o sao chépớ ọ ớ ạ đ kh i gán v theo u.ể ở
Ví d sau s minh h a cách dùng hàm t o sao chép m c đ nh:ụ ẽ ọ ạ ặ ị Trong chương trình đ a vào l p ư ớ PS (phân s ):ố
+ Các thu c tính g m: t (t s ) và m (m u).ộ ồ ử ố ẫ
+ Trong l p không có phớ ương th c nào c mà chứ ả ỉ có 2 hàm b n là các hàmạ toán t nh p (>>) và xu t (<<). ử ậ ấ
+ N i dung chộ ương trình là: Dùng l nh khai báo đ t o m t đ i tệ ể ạ ộ ố ượng u (ki u PS) có n i dung nh đ i tể ộ ư ố ượng đã có d.
// Ham tao sao chep mac dinh #include <conio.h> #include <iostream.h> class PS { private: int t, m ; public:
friend ostream& operator<< (ostream&os, const PS &p) {
os << " = " << p.t << "/" << p.m; return os;
}
friend istream& operator>> (istream& is, PS &p) {
cout << "\n Nhap tu va mau: " ; is >> p.t >> p.m ; return is; } } ; void main() { PS d;
cout << "\n PS d " << d; PS u(d); cout << "\n PS u "<< u; getch(); } 2. Cách xây d ng hàm t o sao chépự ạ
+ Hàm t o sao chép s d ng m t đ i ki u tham chi u đ i tạ ử ụ ộ ố ể ế ố ượng đ kh iể ở gán cho đ i tố ượng m i. Hàm t o sao chép đớ ạ ược vi t theo m u:ế ẫ
Tên_l p (const Tên_l p & dt)ớ ớ {
// Các câu l nh dùng các thu c tính c a đ i tệ ộ ủ ố ượng dt // đ kh i gán cho các thu c tính c a đ i tể ở ộ ủ ố ượng m iớ }
+ Ví d có th xây d ng hàm t o sao chép cho l p PSụ ể ự ạ ớ nh sau:ư class PS { private: int t, m ; public: PS (const PS &p) { this->t = p.t ; this->m = p.m ; } ... } ;
3. Khi nào c n xây d ng hàm t o sao chépầ ự ạ
+ Nh n xét: Hàm t o sao chép trong ví d trên không khác gì hàm t o saoậ ạ ụ ạ chép m c đ nh.ặ ị
+ Khi l p không có các thu c tính ki u con tr ho c tham chi u, thì dùngớ ộ ể ỏ ặ ế hàm t o sao chép m c đ nh là đ . ạ ặ ị ủ
+ Khi l p có các thu c tính con tr ho c tham chi u, thì hàm t o sao chépớ ộ ỏ ặ ế ạ m c đ nh ch a đáp ng đặ ị ư ứ ược yêu c u. ầ
Ví d :ụ class DT {
private:
int n; // Bac da thuc
double *a; // Tro toi vung nho chua cac he so da thuc a0, a1, ... public:
DT() { this->n0; this->a = NULL; } DT(int n1)
{
this->n = n1;
this->a = new double[n1+1]; }
friend ostream& operator << (ostream& os, const DT &d); friend istream& operator>> (istream& is, DT &d);
... } ;
Bây gi chúng ta hãy theo dõi xem vi c dùng hàm t o m c đ nh trong đo nờ ệ ạ ặ ị ạ chương trình sau s d n đ n sai l m nh th nào:ẽ ẫ ế ầ ư ế
DT d ; // T o đ i tạ ố ượng d ki u DTể cin >> d ;
/* Nh p đ i tậ ố ượng d, g m: nh p m t s nguyên dồ ậ ộ ố ương và gán cho d.n, c p phátấ vùng nh cho d.a, nh p các h s c a đa th c và ch a vào vùng nh đớ ậ ệ ố ủ ứ ứ ớ ược c pấ phát */
DT u(d);
/* Dùng hàm t o m c đ nh đ xây d ng đ i tạ ặ ị ể ự ố ượng u theo d. K t qu : u.n = d.n vàế ả u.a = d.a. Nh v y 2 con tr u.a và d.a cùng tr đ n m t vùng nh */ ư ậ ỏ ỏ ế ộ ớ
Nh n xét:ậ M c đích là t o ra m t đ i tụ ạ ộ ố ượng u gi ng nh d, nh ng đ c l pố ư ư ộ ậ v i d. Nghĩa là khi d thay đ i thì u không b nh hớ ổ ị ả ưởng gì. Th nh ng m c tiêu nàyế ư ụ không đ t đạ ược, vì u và d có chung m t vùng nh ch a h s c a đa th c, nên khiộ ớ ứ ệ ố ủ ứ s a đ i các h s c a đa th c trong d thì các h s c a đa th c trong u cũng thayử ổ ệ ố ủ ứ ệ ố ủ ứ đ i theo. Còn m t trổ ộ ường h p n a cũng d n đ n l i là khi m t trong 2 đ i tợ ữ ẫ ế ỗ ộ ố ượng u và d b gi i phóng (thu h i vùng nh ch a đa th c) thì đ i tị ả ồ ớ ứ ứ ố ượng còn l i cũng sạ ẽ không còn vùng nh n a.ớ ữ
Ví d sau s minh h a nh n xét trên: Khi d thay đ i thì u cũng thay đ i vàụ ẽ ọ ậ ổ ổ ngượ ạc l i khi u thay đ i thì d cũng thay đ i theo.ổ ổ
#include <conio.h> #include <iostream.h> #include <math.h> class DT { private:
int n; // Bac da thuc
double *a; // Tro t i vung nho chua cac he so da thuc a0, a1 , ...ơ public:
DT() { this->n = 0; this->a = NULL; } DT(int n1)
{
this->n = n1 ;
this->a = new double[n1+1]; }
friend ostream& operator<< (ostream& os, const DT &d); friend istream& operator>> (istream& is, DT &d);
} ;
ostream& operator<< (ostream& os, const DT &d) {
os << " Cac he so (tu ao): "; for (int i = 0 ; i< = d.n ; ++i) os << d.a[i] <<" " ;
return os; }
istream& operator >> (istream& is, DT &d) {
if (d.a! = NULL) delete d.a; cout << " \n Bac da thuc: " ; cin >> d.n;
d.a = new double[d.n+1];
for (int i = 0 ; i< = d.n ; ++i) {
cout << "He so bac "<< i << " = " ; is >> d.a[i] ; } return is; } void main() { DT d; clrscr();
cout <<"\n Nhap da thuc d " ; cin >> d; DT u(d);
cout << "\n Da thuc d "<< d ; cout << "\n Da thuc u " << u ;
cout <<"\n Nhap da thuc d " ; cin >> d; cout << "\nDa thuc d " << d;
cout <<"\n Da thuc u " << u ;
cout <<"\n Nhap da thuc u " ; cin >> u; cout << "\n Da thuc d "<< d ;
cout << "\n Da thuc u " << u ; getch();
}
4. Ví d v hàm t o sao chépụ ề ạ
Trong chương trình trên đã ch rõ: Hàm t o sao chép m c đ nh là ch a thoỉ ạ ặ ị ư ả mãn đ i v i l p DT. Vì v y c n vi t hàm t o sao chép đ xây d ng đ i tố ớ ớ ậ ầ ế ạ ể ự ố ượng m i (ví d u) t m t đ i tớ ụ ừ ộ ố ượng đang t n t i (ví d d) theo các yêu c u sau:ồ ạ ụ ầ
+ Gán d.n cho u.n
+ C p phát m t vùng nh cho u.a đ có th ch a đấ ộ ớ ể ể ứ ược (d.n + 1) h s .ệ ố + Gán các h s ch a trong vùng nh c a d.a sang vùng nh c a u.aệ ố ứ ớ ủ ớ ủ
Nh v y chúng ta s t o đư ậ ẽ ạ ược đ i tố ượng u có n i dung ban đ u gi ng nh d,ộ ầ ố ư nh ng đ c l p v i d.ư ộ ậ ớ
DT::DT(const DT &d) {
this → n = d.n ;
this → a = new double[d.n+1]; for (int i = 0; i< = d.n; ++i) this → a[i] = d.a[i];
}
Chương trình sau s minh h a đi u này: S thay đ i c a d không làm nhẽ ọ ề ự ổ ủ ả hưởng đ n u và ngế ượ ạ ực l i s thay đ i c a u không làm nh hổ ủ ả ưởng đ n d.ế
// Vi t hàm t o sao chép cho l p DTế ạ ớ #include <conio.h> #include <iostream.h> #include <math.h> class DT { private:
int n; // Bac da thuc
double *a; // Tro toi vung nho chua cac he so da thuc a0, a1 , ... public:
DT() { this → n = 0; this → a = NULL; } DT(int n1)
{
this → n = n1 ;
this → a = new double[n1+1]; }
DT(const DT &d);
friend ostream& operator<< (ostream& os, const DT&d); friend istream& operator>> (istream& is, DT&d);
};
DT::DT(const DT&d) {
this → a = new double[d.n+1]; for (int i = 0; i< = d.n; ++i) this → a[i] = d.a[i];
}
ostream& operator<< (ostream& os, const DT &d) {
os << " Cac he so (tu ao): " ;
for (int i = 0 ; i< = d.n ; ++i) os << d.a[ i] <<" " ; return os;
}
istream& operator>> (istream& is, DT &d) {
if (d.a! = NULL) delete d.a; cout << "\n Bac da thuc: '' ; cin >> d.n;
d.a = new double[d.n+1];
cout << ''Nhap cac he so da thuc:\n'' ; for (int i = 0 ; i< = d.n ; ++i)
{
cout << "He so bac " << i << " = " ; is >> d.a[i] ; } return is; } void main() { DT d; clrscr();
cout <<"\n Nhap da thuc d " ; cin >> d; DT u(d);
cout <<"\n Da thuc d " << d ; cout << "\n Da thuc u " << u ;
cout <<"\n Nhap da thuc d " ; cin >> d; cout << "\n Da thuc d "<< d ;
cout <<"\n Da thuc u " << u ;
cout <<"\n Nhap da thuc u " ; cin >> u; cout << "\n Da thuc d " << d ;
cout <<"\n Da thuc u " << u ; getch();
}