intTypePromotion=1
zunia.vn Tuyển sinh 2024 dành cho Gen-Z zunia.vn zunia.vn
ADSENSE

Chương 4

Chia sẻ: Huongdanhoctot_4 Huongdanhoctot_4 | Ngày: | Loại File: PDF | Số trang:45

48
lượt xem
4
download
 
  Download Vui lòng tải xuống để xem tài liệu đầy đủ

Hàm tạo không có kết quả trả về. 1.2.2. Sự giống nhau của hàm tạo và các phương thức thông thường Ngoài 3 điểm khác biệt trên, hàm tạo được viết như các phương thức khác: + Hàm tạo có thể được xây dựng bên trong hoặc bên ngoài định nghĩa lớp.

Chủ đề:
Lưu

Nội dung Text: Chương 4

  1. + Hàm tạo không có kết quả trả về. Chương 4 Hàm tạo, hàm huỷ và các 1.2.2. Sự giống nhau của hàm tạo và các phương thức thông vấn đề liên quan thường Ngoài 3 điểm khác biệt trên, hàm tạo được viết như các phương Chương này trình bầy một số vấn đề có tính chuyên sâu hơn về thức khác: lớp như: + Hàm tạo có thể được xây dựng b ên trong hoặc bên ngoài định + Hàm tạo (constructor) nghĩa lớp. + Hàm hu ỷ (destructor) + Hàm tạo có thể có đối hoặc không có đối. + Toán tử gán và hàm tạo sao chép + Trong một lớp có thể có nhiều hàm tạo (cùng tên nhưng khác bộ + Mối liên quan giữa hàm tạo và đối tượng thành phần đối). + Các thành phần tĩnh Ví dụ sau định nghĩa lớp DIEM_DH (Điểm đồ hoạ) có 3 thuộc + Lớp bạn, hàm bạn tính: + Đối tượng hằng int x; // hoành độ (cột) của điểm + Phương thức inline int y; // tung độ (hàng) của điểm int m; // mầu của điểm § 1. Hàm tạo (constructor) và đưa vào 2 hàm tạo để khởi gán cho các thuộc tính của lớp: 1.1. Công dụng // Hàm tạo không đối: Dùng các giá trị cố định để khởi gán cho Hàm tạo cũng là một phương thức của lớp (nhưng khá đ ặc biệt) // x, y, m dùng đ ể tạo dựng một đối tượng mới. Chương trình d ịch sẽ cấp phát DIEM_DH() ; bộ nhớ cho đối tượng sau đó sẽ gọi đến hàm tạo. Hàm tạo sẽ khởi gán giá trị cho các thuộc tính của đối tượng và có thể thực hiện một // Hàm tạo có đối: Dùng các đối x1, y1, m1 để khởi gán cho số công việc khác nhằm chuẩn bị cho đối tượng mới. // x, y, m // Đối m1 có giá trị mặc định 15 (mầu trắng) 1.2. Cách viết hàm tạo DIEM_DH(int x1, int y1, int m1=15) ; 1.2.1. Điểm khác của hàm tạo và các phương thức thông class DIEM_DH thường { Khi viết hàm tạo cần để ý 3 sự khác biệt của hàm tạo so với các private: phương thức khác như sau: int x, y, m ; + Tên của hàm tạo: Tên của hàm tạo bắt buộc phải trùng với tên của lớp. public: + Không khai báo kiểu cho hàm tạo. //Hàm tạo không đối: khởi gán cho x=0, y=0, m=1 150 151
  2. // Hàm này viết b ên trong đ ịnh nghĩa lớp // Kết quả d.x=0, d.y=0, d.m=1 DIEM_DH u(200,100,4); // Gọi tới hàm tạo có đối. DIEM_DH() 152 // Kết quả u.x=200, u.y=100, d.m=4 { x=y=0; DIEM_DH v(300,250); // Gọi tới hàm tạo có đối. m=1; // Kết quả v.x=300, v.y=250, d.m=15 } DIEM_DH p[10] ; // Gọi tới hàm tạo không đối 10 lần // Hàm tạo này xây dựng b ên ngoài định nghĩa lớp Chú ý: Với các hàm có đối kiểu lớp, thì đối chỉ xem là các tham DIEM_DH(int x1, int y1, int m1=15) ; số hình thức, vì vậy khai báo đối (trong dòng đầu của hàm) sẽ không tạo ra đối tượng mới và do đó không gọi tới các hàm tạo. // Các phương thức khác }; 1.4. Dùng hàm tạo trong cấp phát bộ nhớ // Xây d ựng hàm tạo bên ngoài định nghĩa lớp + Khi cấp phát bộ nhớ cho một đối tượng có thể dùng các tham số DIEM_DH:: DIEM_DH(int x1, int y1, int m1) để khởi gán cho các thuộc tính của đối tượng, ví dụ: { DIEM_DH *q =new DIEM_DH(50,40,6);//Gọi tới hàm tạo có đối x=x1; y=y1; m=m1; // Kết quả q ->x=50, q->y=40, q->m=6 } DIEM_DH *r = new DIEM_DH ; // Gọi tới hàm tạo không đối // Kết quả r->x=0, r->y= 0, r->m=1 1.3. Dùng hàm tạo trong khai báo + Khi đ ã xây d ựng các hàm tạo, ta có thể dùng chúng trong khai + Khi cấp phát bộ nhớ cho một dẫy đối tượng không cho phép báo để tạo ra một đối tượng đồng thời khởi gán cho các thuộc tính dùng tham số để khởi gán, ví dụ: của đối tượng đ ược tạo. Dựa vào các tham số trong khai báo mà int n=20; Trình biên dịch sẽ biết cần gọi đến hàm tạo nào. DIEM_DH *s = new DIEM_DH[n] ; // Gọi tới hàm tạo không + Khi khai báo một biến đối tượng có thể sử dụng các tham số để // đối 20 lần. khởi gán cho các thuộc tính của biến đối tượng. + Khi khai báo mảng đối tượng không cho phép dùng các tham số 1.5. Dùng hàm tạo để biểu diễn các đối tượng hằng để khởi gán. + Như đ ã biết, sau khi định nghĩa lớp DIEM_DH thì có thể xem + Câu lệnh khai báo một biến đối tượng sẽ gọi tới hàm tạo 1 lần lớp này như một kiểu dữ liệu như int, double, char, ... + Câu lệnh khai báo một mảng n đối tượng sẽ gọi tới hàm tạo n Với kiểu int chúng ta có các hằng int, như 356. lần. Với kiểu double chúng ta có các hằng double, như 98.75 Ví dụ: Khái niệm hằng kiểu int, hằng kiểu double có thể mở rộng cho hằng kiểu DIEM_DH DIEM_DH d; // Gọi tới hàm tạo không đối.
  3. + Để biểu diễn một hằng đối tượng (hay còn gọi: Đối tượng hằng) // Phương thức dùng đ ể in đối tượng DIEM_DH chúng ta phải d ùng tới hàm tạo. Mẫu viết như sau: void in() { Tên_lớp(danh sách tham số) ; cout
  4. in(*d); //Gọi hàm b ạn in() # include DIEM_DH(2,2,2).in();//Gọi phương thức in() class DIEM_DH DIEM_DH t[3]; // 3 lần gọi hàm tạo không đối { DIEM_DH *q; // Gọi hàm tạo không đối private: int n; int x,y,m; 156 cout > n; // Phuong thuc q=new DIEM_DH[n+1]; // (n+1) lần gọi hàm tạo không đối void in() for (int i=0;i
  5. xẩy ra khi chúng ta không xây dựng hàm tạo không đối, nhưng lại sử } dụng các khai báo không tham số như ví dụ sau: Trong các câu lệnh trên, chỉ có câu lệnh thứ 2 trong hàm main() là # include bị báo lỗi. Câu lệnh này sẽ gọi tới hàm tạo không đối, mà hàm này # include chưa được xây dựng. class DIEM_DH Giải pháp: Có thể chọn một trong 2 giải pháp sau: { - Xây dựng thêm hàm tạo không đối. p rivate: - Gán giá trị mặc định cho tất cả các đối x1, y1 và m1 của hàm tạo int x,y,m; đã xây d ựng ở trên. 158 public: Theo phương án 2, chương trình có thể sửa như sau: // Phương thức dùng đ ể in đối tượng DIEM_DH # include void in() # include class DIEM_DH { { cou t
  6. // tham số mặc định + Dùng khai báo đ ể tạo các đối tượng, ví dụ: DIEM_DH d2; // Gọi tới hàm tạo , dùng 3 tham số mặc định DT d; d2= DIEM_DH(300,300); // Gọi tới hàm tạo, dùng 1 tham số + Cấp phát vùng nhớ (cho đối tượng) để chứa đa thức, ví dụ: // mặc định d.n = m; d1.in(); d.a = new double[m+1] ; d2.in(); Quy trình này được áp dụng trong các phương thức toán tử của getch(); chương trình trong mục 8.5 chương 3. Rõ ràng quy trình này vừa d ài } vừa không tiện lợi, lại hay mắc lỗi, vì người lập trình hay quên không cấp phát bộ nhớ. Việc dùng các hàm tạo để sản sinh ra các đối tượng hoàn chỉnh tỏ § 3. Lớp đa thức r60tiện lợi hơn, vì tránh được các thao tác phụ (như cấp phát bộ nhớ) a 1 Chương trình d ưới đây là sự cải tiến chương trình trong mục 8.5 nằm bên ngoài khai báo. Phương án dùng hàm tạo sẽ đ ược sử dụng của chương 3 bằng cách đ ưa vào 2 hàm tạo: trong các phương thức toán tử của chương trình dưới đây: //Hàm tạo không đối + Nội dung chương trình gồm: DT() - Nhập, in các đa thức p, q, r, s { - Tính đa thức: f = -(p + q)*(r - s) this->n=0; this->a=NULL; - Nhập các số thực x1 và x2 } - Tính f(x1) (bằng cách dùng phương thức operator^) //Hàm tạo có đối - Tính f(x2) (bằng cách dùng hàm F) DT(int n1) // CT4_05.CPP { # include this->n=n1 ; # include this->a = new double[n1+1]; # include } class DT Hàm tạo có đối sẽ tạo một đối tượng mới (kiểu DT) gồm 2 thuộc { tính là biến nguyên n và con trỏ a. Ngoài ra còn cấp phát bộ vùng private: nhớ (cho a) để chứa các hệ số của đa thức. int n; // Bac da thuc Nếu không xây dựng hàm tạo, mà sử dụng hàm tạo mặc định thì double *a; // Tro toi vung nho chua cac he so da thuc các đối tượng (kiểu DT) tạo ra bởi các lệnh khai báo sẽ chưa có bộ // a0, a1,... nhớ để chứa đa thức. Như vậy đối tượng tạo ra chưa hoàn chỉnh và chưa dùng được. Để có một đối tượng ho àn chỉnh phải qua 2 b ước:
  7. public: double s=0.0 , t=1.0; DT() int n; { n = int(d[-1]); this->n=0; this->a=NULL; for (int i=0; in=n1 ; } this->a = new double[n1+1]; return s; } } friend ostream& operator (istream& is,DT &d); 162 { DT operator-(); os
  8. DT DT::operator-(DT d2) } return is; { } return (*this + (-d2)); } DT DT::operator-() DT DT::operator*(const DT &d2) { DT p(this->n); { for (int i=0 ; i
  9. DT p,q,r,s,f; PS p1, p2 ; double x1,x2,g1,g2; 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ừ clrscr(); một đối tượng đ ã tồn tại, ví dụ: cout p; PS u; cout
  10. # include 4.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 class PS để khởi gán cho đối tượng mới. Hàm tạo sao chép được viết theo { mẫu: p rivate: Tên_lớp (const Tên_lớp & dt) int t,m ; { public: // Các câu lệnh d ùng các thuộc tính của đối tượng dt friend ostream& operator p .m ; 168 PS (const PS &p) return is; { } this->t = p.t ; }; this->m = p.m ; void main() } { ... PS d; }; cout > d; 4.3. Khi nào cần xây dựng hàm tạo sao chép cout
  11. + Khi lớp có các thuộc tính con trỏ hoặc tham chiếu, thì hàm tạo /* Nhập đối tượng d , gồm: nhập một số nguyên dương và sao chép mặc định chưa đáp ứng được yêu cầu. Ví dụ lớp DT (đa gán cho d.n, cấp phát vùng nhớ cho d.a, nhập các hệ số thức) trong §3: của đa thức và chứa vào vùng nhớ đ ược cấp phát class DT */ { DT u(d) ; p rivate: /* Dùng hàm tạo mặc định để xây dựng đối tượng u theo d int n; // Bac da thuc Kết quả: u.n = d.n và u.a = d.a. Như vậy 2 con trỏ u.a và double *a; // Tro toi vung nho chua cac he so da thuc d.a cùng trỏ đến một vùng nhớ. // a0, a1,... */ public: Nhận xét: Mục đích của ta là tạo ra một đối tượng u giống như d, DT() 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ó this->n=0; this->a=NULL; 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 DT(int n1) đố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. this->n=n1 ; Ví d ụ sau sẽ minh hoạ nhận xét trên: Khi d thay đổi thì u cũng this->a = new double[n1+1]; t70 đổi và ngược lại khi u thay đổi thì d cũng thay đổi theo. hay 1 } //CT4_07.CPP friend ostream& operator> (istream& is,DT &d); # include .... class DT }; { Bây giờ chúng ta hãy theo rõi xem việc dùng hàm tạo mặc định private: trong đo ạn chương trình sau sẽ dẫn đến sai lầm như thế nào: int n; // Bac da thuc DT d ; double *a; // Tro toi vung nho chua cac he so da thuc // Tạo đối tượng d kiểu DT // a0, a1,... public: cin >> d ;
  12. DT() } { return is; this->n=0; this->a=NULL; } } void main() DT(int n1) { { DT d; this->n=n1 ; clrscr(); this->a = new double[n1+1]; cout d; } friend ostream& operator> (istream& is,DT &d); cout
  13. Như vây chúng ta sẽ tạo được đối tượng u có nội dung ban đầu this->n=0; this->a=NULL; giống như d, nhưng độc lập với d. } Để đáp ứng các yêu cầu nêu trên, hàm tạo sao chép cần được xây DT(int n1) dựng như sau: { DT::DT(const DT &d) this->n=n1 ; { this->a = new double[n1+1]; this->n = d.n; } this->a = new double[d.n+1]; DT(const DT &d); for (int i=0;i> (istream& is,DT &d); } }; Chương trình sau sẽ minh hoạ điều này: Sự thay đổi của d không DT::DT(const DT &d) 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. this->n = d.n; //CT4_08.CPP this->a = new double[d.n+1]; // Viết hàm tạo sao chép cho lớp DT for (int i=0;ia[i] = d.a[i]; # include } # include o stream& operator
  14. if (d.a!=NULL) delete d.a; } cout > d.n; d.a = new double[d.n+1]; § 5. Hàm huỷ (Destructor) cout
  15. Ví d ụ có thể xây dựng hàm hu ỷ cho lớp DT (đa thức) ở §3 như được tạo ra. Một vùng nhớ đ ược cấp phát và giao cho nó (đối tượng trung gian) qu ản lý. sau: + Khi thực hiện xong phép tính sẽ ra khỏi phương thức. Đối class DT tượng trung gian bị xoá, tuy nhiên chỉ vùng nhớ của các thuộc tính { của đối tượng này được giải phóng. Còn vùng nhớ (chứa các hệ số p rivate: của đa thức) mà đối tượng trung gian đang quản lý thì không hề bị giải phóng. Như vậy số vùng nhớ bị chiếm dụng vô ích sẽ tăng lên. int n; // Bac da thuc double *a; // Tro toi vung nho chua cac he so da thuc 5.4.2. Cách khắc phục // a0, a1,... Nhược điểm trên d ễ d àng khắc phục bằng cách đưa vào lớp DT public: hàm hu ỷ viết trong 5.3 (mục trên). ~DT() 5.5. Lớp hình tròn đồ hoạ { Chương trình d ưới đây gồm: this->n=0; Lớp HT (h ình tròn) với các thuộc tính: delete this->a; int r; // Bán kính } int m ; // Mầu hình tròn ... int xhien,yhien; // Vị trí hiển thị hình tròn trên màn hình }; // Con trỏ trỏ tới vùng nhớ chứa ảnh hình tròn char *pht; 5.4. Vai trò của hàm huỷ trong lớp DT // Trạng thái hiện (hienmh=1), ẩn (hienmh=0) int hienmh; Các phương thức: 5.4.1. Khiếm khuyết của chương trình trong §3 + Hàm tạo không đối Chương trình trong §3 đ ịnh nghĩa lớp DT (đa thức) khá đầy đủ HT(); gồm: thực hiện việc gán giá trị bằng 0 cho các thuộc tính của lớp. + Các hàm tạo + Hàm tạo có đối + Các hàm toán tử nhập >>, xuất
  16. + Hàm hu ỷ # include ~HT(); # include thực hiện các việc: void ktdh(); - Xoá hình tròn khỏi màn hình (nếu đang hiển thị) void ve_bau_troi(); - Giải p hóng bộ nhớ đã cấp cho pht void ht_di_dong_xuong(); + Phương thức void ht_di_dong_len(); void hien(int x, int y); int xmax,ymax; có nhiệm vụ hiển thị hình tròn tại (x,y) class HT + Phương thức { void an(); private: có nhiệm vụ làm ẩn hình tròn int r,m ; int xhien,yhien; Các hàm độc lập: char *pht; void ktdh(); //Khởi tạo đồ hoạ int hienmh; void ve_bau_troi(); // Vẽ bầu trời đầy sao public: void ht_di_dong_xuong(); // Vẽ một cặp 2 hình tròn di HT(); // chuyển xuống HT(int r1,int m1=15); void ht_di_dong_len();// Vẽ một cặp 2 hình tròn di ~HT(); // chuyển lên trên void hien(int x, int y); Nội dung chương trình là tạo ra các chuyển động xuống và lên của các hình tròn. void an(); //CT4_09.CPP }; // Lop do hoa HT:: HT() // Ham huy { // Trong ham huy co the goi PT khac r=m=hienmh=0; # include xhien=yhien=0; # include pht=NULL; # include } # include
  17. HT::HT(int r1,int m1) if (pht!=NULL && !hienmh) // chua hien { { hienmh=1; 180 r=r1; m=m1; hienmh=0; 181 xhien=x; yhien=y; xhien= yhien=0; putimage(x,y,pht,XOR_PUT); if (r
  18. ymax = getmaxy(); HT u(60,15); } h.hien(340,340); u.hien(380,340); 182 oid ve_bau_troi() v for (int x=340;x>=0;x-=10) 183 { { h.an(); for (int i=0;i
  19. bị thu hồi, nhưng vùng nhớ cấp phát cho thuộc tính pht chưa được Phương thức toán tử gán có thể có hoặc không có giá trị trả về. giải phóng và ảnh của 2 hình tròn (ở phía dưới màn hình) vẫn không Nếu không có giá trị trả về (kiểu void), thì khi viết chương trình được cất đi. không được phép viết câu lệnh gán liên tiếp nhiều đối tượng, như: + Điều tương tự xẩy ra sau khi ra khỏi hàm ht_di_dong_len() : u=v=k=h; vùng nhớ cấp phát cho thuộc tính pht chưa được giải phóng và ảnh Nếu phương thức toán tử gán trả về tham chiếu của đối tượng của 2 hình tròn (ở phía trên màn hình) vẫn không đ ược thu dọn. nguồn, thì có thể dùng toán tử gán thể thực hiện các phép gán liên tiếp nhiều đối tượng. 184 185 Ví dụ đối với lớp HT (trong mục trước), có thể xây dựng toán tử § 6 . Toán tử gán gán như sau: 6.1. Toán tử gán mặc định void HT::operator=(const HT &h) Toán tử gán (cho lớp) là một trường hợp đặc biệt so với các toán { tử khác. Nếu trong lớp chưa đ ịnh nghĩa một phương thức toán tử gán r = h.r ; m = h.m ; thì Trình biên dịch sẽ phát sinh một toán tử gán mặc định để thực hiện câu lệnh gán 2 đối tượng của lớp, ví du: xhien = yhien = 0; HT h1, h2(100,6); hienmh = 0 ; h1 = h2 ; // Gán h2 cho h1 if (h.pht==NULL) Toán tử gán mặc định sẽ sẽ sao chép đối tượng nguồn (h2) vào pht = NULL; đối tượng đích (h1) theo từng bit một. else Trong đa số các trường hợp khi lớp không có các thành phần con { trỏ hay tham chiếu thì toán tử gán mặc định là đ ủ dùng và không cần int size; định nghĩa một phương thức toán tử gán cho lớp. Nhưng đ ối với các lớp có thuộc tính con trỏ như lớp DT (đa thức), lớp HT (hình tròn) size = imagesize(0,0,r+r,r+r); thì toán tử gán mặc định không thích hợp và việc xây dựng toán tử p ht = new char[size]; gán là cần thiết. memcpy(pht,h.pht,size); 6.2. Cách viết toán tử gán } Cũng giống như các phương thức khác, phương thức toán tử gán } dùng đối con trỏ this để biểu thị đối tượng đích và dùng một đối Với toán tử gán này, chỉ cho phép gán đối tượng ngu ồn cho một tường minh để biểu thị đối tượng nguồn. Vì trong thân của toán tử đối tượng đích. gán không nên làm việc với bản sao của đối tượng nguồn, mà phải Như vậy câu lệnh sau là sai: làm việc trực tiếp với đối tượng nguồn, nên kiểu đối tường minh nhất thiết phải là kiểu tham chiếu đối tượng. HT u, v, h ; u=v=h;
  20. Bây giờ ta sửa lại toán gán để nó trả về tham chiếu đối tượng + Nếu đã xây d ựng toán tử gán mà lại dùng hàm tạo sao chép mặc nguồn như sau: định thì chưa đủ, vì việc khởi gán trong câu lệnh khai báo sẽ không gọi tới toán tử gán mà lại gọi tới hàm tạo sao chép. const HT & HT::operator=(const HT &h) + Như vậy đối với lớp có thuộc tính con trỏ, thì ngoài hàm tạo, { cần xây dựng thêm: r = h.r ; m = h.m ; - Hàm hu ỷ xhien = yhien = 0; - Hàm tạo sao chép hienmh = 0 ; - Phương thức toán tử gán if (h.pht==NULL) Chú ý: Không phải mọi câu lệnh chứa có dấu = đều gọi đến toán p ht = NULL; tử gán. Cần phân biệt 3 trường hợp: else 1. Câu lệnh new (chứa dấu =) sẽ gọi đến hàm tạo, ví dụ: 186 187 { HT *h= new HT(50,6); // gọi đến hàm tạo có đối int size; 2. Câu lệnh khai báo và khởi gán (dùng dấu =) sẽ gọi đến hàm tạo size = imagesize(0,0,r+r,r+r); sao chép, ví dụ: p ht = new char[size]; // gọi đến hàm tạo sao chep HT k=*h; memcpy(pht,h.pht,size); 3. Câu lệnh gán sẽ gọi đến toán tử gán, ví dụ: } HT u; return h ; u=*h; // gọi đến phương thức toán tử gán } 6.4. Ví dụ minh hoạ Với toán tử gán mới này, ta có thể viết câu lệnh để gán đối tượng Chương trình d ưới đây định nghĩa lớp HT (hình tròn) và minh nguồn cho nhiều đối tượng đích. Như vậy các câu lệnh sau là được: ho ạ: HT u, v, h ; + Hàm tạo và hàm hu ỷ u=v=h; + Phương thức toán tử gán có kiểu tham chiếu 6.3. Toán tử gán và hàm tạo sao chép + Hàm tạo sao chép + Toán tử gán không tạo ra đối tượng mới, chỉ thực hiện phép gán + Cách dùng con trỏ this trong hàm tạo sao chép giữa 2 đối tượng đ ã tồn tại. + Cách dùng con trỏ _new_handler để kiểm tra việc cấp phát + Hàm tạo sao chép được dùng đ ể tạo một đối tượng mới và gán bộ nhớ. nội dung của một đối tượng đã tồn tại cho đối tượng mới vừa tạo. //CT4_10.CPP // Lop do hoa
ADSENSE

CÓ THỂ BẠN MUỐN DOWNLOAD

 

Đồng bộ tài khoản
2=>2