Hàm to sao chép ạ (Copy Constructor)

Một phần của tài liệu Chương 7. Lớp và đối tượng doc (Trang 27 - 35)

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();

}

Một phần của tài liệu Chương 7. Lớp và đối tượng doc (Trang 27 - 35)

Tải bản đầy đủ (PDF)

(46 trang)