Bài giảng Lập trình hướng đối tượng C++ - Chương 5: Hàm xây dựng, hàm hủy và việc khởi tạo đối tượng

pdf 20 trang Gia Huy 17/05/2022 3171
Bạn đang xem tài liệu "Bài giảng Lập trình hướng đối tượng C++ - Chương 5: Hàm xây dựng, hàm hủy và việc khởi tạo đối tượng", để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên

Tài liệu đính kèm:

  • pdfbai_giang_lap_trinh_huong_doi_tuong_c_chuong_5_ham_xay_dung.pdf

Nội dung text: Bài giảng Lập trình hướng đối tượng C++ - Chương 5: Hàm xây dựng, hàm hủy và việc khởi tạo đối tượng

  1. Chương 5 HÀM XÂY DỰNG, HÀM HỦY VÀ VIỆC KHỞI TẠO ĐỐI TƯỢNG 1
  2. Nội dung • Hàm xây dựng • Hàm hủy • Hàm xây dựng sao chép • Thuộc tính của 1 lớp là đối tượng 2
  3. Hàm xây dựng • Mục đích: khởi tạo giá trị ban đầu cho đối tượng – Gán giá trị đầu cho các thuộc tính. – Cấp vùng nhớ cho con trỏ thành viên. class Diem { class PhanSo { int x, y; int tu, mau; public: public: Diem(int a) PhanSo() { x = y = a; } { tu=0; mau=1; } Diem(int h, int t) PhanSo(int x) { x = h; y=t; } { tu=x; mau=1; } . PhanSo(int t, int m) }; { tu = t; mau=m; } . }; 3
  4. Hàm xây dựng • Ví dụ: class SinhVien { class Stack { char mssv[8]; float *ds; char* hoten; int soluong; int namsinh; int vitri; float diemtb; public: Cấp vùng public: Stack(int max = 10) nhớ SinhVien() { { cho con trỏ strcpy(mssv,””); soluong = max; hoten = new char[50]; vitri = 0; namsinh = 1980; ds = new diemtb = 0; float[soluong]; } } SinhVien(char*,char*,int,fl Stack(float* d, int m, oat); int n); }; }; 4
  5. Hàm xây dựng • Nếu không có định nghĩa hàm xây dựng: – Mặc nhiên sẽ tự động có 1 hàm xây dựng không tham số. – Chỉ có 1 cách khởi tạo đối tượng theo dạng không tham số. class Diem { void main() { int x, y; Diem a; public: Diem *pa = new Diem(); void InDiem(); Diem ds1[10]; void NhapDiem(); Diem *ds2 = new void GanGiaTri(int, Diem[20]; int); int GiaTriX(); } int GiaTriY(); 1000H x Không có giá trị }; y đầu // Định nghĩa các hàm a nên dễ gây ra thành viên hiệu ứng phụ 5
  6. Hàm xây dựng • Nếu có định nghĩa ít nhất 1 hàm xây dựng: – Có bao nhiêu hàm xây dựng sẽ có bấy nhiêu cách khởi tạo đối tượng theo dạng đã định nghĩa. void main() { void main() { PhanSo a; Stack a; PhanSo b(3); Stack b(5); PhanSo c(2,5); Stack c[5]; PhanSo d[3]; Stack *pa = new Stack(); PhanSo *pa = new PhanSo; Stack *pb = new Stack(40); PhanSo *pa1 = new PhanSo(); Stack *pc = new Stack[40]; PhanSo *pa2 = new PhanSo[5]; float data[40]; PhanSo *pb = new PhanSo(3); for(int i=0;i<10;i++) PhanSo *pc = new data[i]=i; PhanSo(2,5); Stack d(data, 30, 10); } } 6
  7. Hàm xây dựng • Trình tự thực hiện: – Đối tượng được tạo ra trước. – Hàm xây dựng sẽ gọi sau trên đối tượng. PhanSo c(2,5); tu tu 2 mau mau 5 c c PhanSo 1000H 1000H 0 0 0 0 0 *pa2 = new 100 tu 100 tu 0 mau 0 mau 1 1 1 1 1 PhanSo[5]; *pa2 *pa2 1200H 120 *ds *ds 0 Stack soluong soluong 5 0 b(5); vitri vitri 7
  8. Hàm hủy • Mục đích: thu hồi vùng nhớ đã cấp cho con trỏ là dữ liệu thành viên => delete con trỏ. class SinhVien { class Stack { char mssv[8]; float *ds; char* hoten; int soluong; int namsinh; int vitri; float diemtb; public: public: Stack(int max = 10) { SinhVien() { soluong = max; strcpy(mssv,””); vitri = 0; hoten = new char[50]; ds = new namsinh = 1980; float[soluong]; diemtb = 0; } } ~SinhVien() { ~Stack() { delete[] hoten; } delete[] ds; } }; }; 8
  9. Hàm hủy • Thứ tự thực hiện: gọi trước khi hủy đối tượng: – Kết thúc 1 hàm mà trong đó ta có khởi tạo đối tượng. – Thu hồi vùng nhớ cho con trỏ đối tượng. Hàm xây dựng được gọi void HamMinhHoa() { Hàm hủy được gọi cho Stack a; đối tượng mà pa đang trỏ Stack *pa = new Stack(8); tới Hàm xây dựng được gọi 5 delete pa; lần Stack *pb = new Stack[5]; Hàm hủy được gọi 5 lần delete[] pb; pb = new Stack(20); Hàm xây dựng được gọi Hàm hủy được gọi cho a } trước khi kết thúc hàm HamMinhHoa() 9
  10. Hàm xây dựng sao chép • Tại sao cần hàm xây dựng sao chép? – Khởi tạo 1 đối tượng có giá trị giống 1 đối tượng khác. – Khác với phép gán (dấu =) • Nếu không định nghĩa hàm xây dựng sao chép: – Ngôn ngữ sẽ tự động tạo ra cho ta: nội dung là gán (=) tương ứng từng thành phần. – Không chính xác khi có dữ liệu thành viên là con trỏ. 10
  11. Hàm xây dựng sao chép 130 1300H Stack a(8); *ds 0 soluong 8 4 3.2 1.4 3 vitri 2 con trỏ sẽ a 130 trỏ *ds 0 8 Stack b(a); soluong cùng 1 địa chỉ 3 vitri nếu không b định nghĩa hàm xây dựng sao chép
  12. Hàm xây dựng sao chép • Cú pháp: (const & ) { Nội dung hàm } VD: Diem(const Diem& d) { } Stack(const Stack& s) { } SinhVien(const SinhVien& sv) { } • Nội dung: – Gán tương ứng các thành phần dữ liệu (không là con trỏ). – Cấp vùng nhớ và sao chép nội dung vùng nhớ từ đối tượng cho trước. VD: Diem(const Diem& d) { x=d.x; y=d.y; } PhanSo(const PhanSo& p) { tu=p.tu; mau=p.mau; } 12
  13. Hàm xây dựng sao chép • Ví dụ: SinhVien nva; class SinhVien { 1 9 2 0 8 9 1 \ char mssv[8]; 0 mssv[] char* hoten; 1240 *hoten 1974 int namsinh; 1 namsinh 8.14 float diemtb; 2 diemtb public: 2 4 N g u y e n c 7 0 o SinhVien(const SinhVien& s){ 6H strcpy(mssv, s.mssv); p N0 g u y e n y hoten = new char[50]; H strcpy(hoten, s.hoten); \ 1 9 2 0 8 9 1 0 mssv[] namsinh = s.namsinh; 2760 *hoten diemtb = s.diemtb; 1974 namsinh } 8.14 diemtb SinhVien x(nva); }; 13
  14. Hàm xây dựng sao chép • Ví dụ: 1 class Stack { Stack a(8); float *ds; 3 *ds 130 0 int soluong; 0 3 1 soluong 8 04 . . int vitri; 2 4 public: vitri 3 H a Stack(const Stack& s) { copy soluong = s.soluong; *ds 157 1 vitri = s.vitri; 0 3 1 soluong 8 54 . . ds = new float[soluong]; 2 4 for(int i=0; i<vitri; i++) vitri 3 7 ds[i]=s.ds[i]; b 0 Stack b(a); } H }; 14
  15. Hàm xây dựng sao chép • Sử dụng trong các trường hợp: – Đối tượng được truyền theo giá trị của đối số 1 hàm. – Trị trả về của hàm là 1 đối tượng. – Tạo ra 1 đối tượng có giá trị giống 1 đối tượng cho trước. class A { A HamThu(A x) { int x; A y(x); public: return y; Có bao A() { x=0; } } nhiêu hàm A(const A& a) { xây dựng x=a.x; void main() { sao chép } A a,b; được gọi? void Hien() { b = HamThu(a); cout<<“x=“<<x; A c = b; } A *d = new A(c); }; } 15
  16. Thuộc tính của 1 lớp là đối tượng • Giới thiệu: – Thuộc tính của 1 lớp có thể có kiểu bất kỳ. – Thuộc tính của 1 lớp có thể là đối tượng của 1 lớp khác. Sử dụng lại 1 lớp, nhưng không phải là thừa kế class Diem { class DuongTron { int x, y; Diem tam; public : int bankinh; Diem(); public: Diem(int , int); DuongTron(); void Nhap(); void Ve(); void Hien(); void Nhap(); void void DoiDiem(int,int); DoiDTron(int,int); int GiaTriX(); float ChuVi(); int GiaTriY(); float DienTich(); }; }; 16
  17. Thuộc tính của 1 lớp là đối tượng • Cách truy xuất: – Khi truy xuất đến thuộc tính là đối tượng, phải thông qua tên của thuộc tính. – Lưu ý đến thuộc tính truy cập (public, private, ) của thành phần dữ liệu và hàm thành viên của lớp tạo ra đối tượng đó để truy xuất hợp lý.
  18. Thuộc tính của 1 lớp là đối tượng Void DuongTron::Ve() { cout >bankinh; } void DuongTron:: DoiDTron(int dx,int dy) { tam.DoiDiem(dx, dy); } 18
  19. Thuộc tính của 1 lớp là đối tượng • Hàm xây dựng: – Phải khởi tạo cho thuộc tính là đối tượng theo dạng hàm xây dựng của lớp đó. DuongTron() : tam() { bankinh=0; } DuongTron(Diem d, int bk) : tam(d) { bankinh=bk; } DuongTron(int x, int y, int bk) : tam(x,y) { bankinh=bk; } DuongTron(const DuongTron& d): tam(d.tam) {bankinh=d.bankinh;} 19
  20. Thuộc tính của 1 lớp là đối tượng • Hàm xây dựng: ■ Nếu có nhiều thuộc tính là đối tượng, khởi tạo các đối tượng này liên tiếp nhau thông qua dấu phẩy (,). ■ Cú pháp này cho phép áp dụng cả với thuộc tính thường. Duongtron(): tam(), bankinh(0) {} Duongtron(Diem d, int bk) : tam(d), bankinh(bk) {} 20