Hàm tạo, hàm huỷ và vai trò của chúng trong lập trình hướng đối tượng

MỤC LỤC

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. 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. Chương trình sau sẽ minh hoạ đ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.

Hàm huỷ là một hàm thành viên của lớp (phương thức) có chức năng ngược với hàm tạo. Hàm huỷ được gọi trước khi giải phóng (xoá bỏ) một đối tượng để thực hiện một số công việc có tính “dọn dẹp”.

Vai trò của hàm huỷ trong lớp DT

Lớp hình tròn đồ hoạ Chương trình dưới đây gồm

- Vẽ hình tròn và lưu ảnh hình tròn vào vùng nhớ của pht + Hàm huỷ. - Xoá hình tròn khỏi màn hình (nếu đang hiển thị) - Giải phóng bộ nhớ đã cấp cho pht. 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.

+ Khi gọi hàm ht_di_dong_xuong() thì có 2 đối tượng kiểu HT được tạo ra. Trong thân hàm sử dụng các đối tượng này để vẽ các hình tròn di chuyển xuống. Vùng nhớ của các thuộc tính của chúng bị thu hồi, nhưng vùng nhớ cấp phát cho thuộc tính pht chưa được 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 được cất đi.

+ Điều tương tự xẩy ra sau khi ra khỏi hàm ht_di_dong_len() : vùng nhớ cấp phát cho thuộc tính pht chưa được giải phóng và ảnh của 2 hình tròn (ở phía trên màn hình) vẫn không được thu dọn. 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. Toán tử gán mặc định sẽ sẽ sao chép đối tượng nguồn (h2) vào đối tượng đích (h1) theo từng bit một.

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 đị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) 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ử gán là cần thiết.

Cách viết toán tử gán

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 nguồn cho nhiều đối tượng đích.

Vai trò của phương thức toán tử gán

+ Với các phương thức toán tử, thì đối ẩn biểu thị toán hạng đối tượng thứ nhất.

Phương thức inline

+ Chú ý là trong các phương thức của lớp bao không cho phép truy nhập trực tiếp đến các thuộc tính của các đối tượng của các lớp thành phần. + Vì vậy, khi xây dựng hàm tạo của lớp bao, phải sư dụng các hàm tạo của lớp thành phần để khởi gán cho các đối tượng thành phần của lớp bao. Ví dụ khi xây dựng hàm tạo của lớp C, cần dùng các hàm tạo của lớp A để khởi gán cho đối tượng thành phần u và dùng các hàm tạo của lớp B để khởi gán cho các đối tượng thành phần p, q.

Cách dùng hàm tạo của lớp thành phần để xây dựng hàm tạo của lớp bao

Chú ý là các dấu ngoặc sau tên đối tượng luôn luôn phải có, ngay cả khi danh sách giá trị bên trong là rỗng. Dựa vào danh sách giá trị, Trình biên dịch sẽ biết cần dùng hàm tạo nào để khởi gán cho đối tượng. Nếu danh sách giá trị là rỗng thì hàm tạo không đối sẽ được sử dụng.

+ Các đối tượng muốn khởi gán bằng hàm tạo không đối có thể bỏ qua, không cần phải liệt kê trong hàm tạo. Nói cách khác: Các đối tượng không được liệt kê trên dòng đầu hàm tạo của lớp bao, đều được khởi gán bằng hàm tạo không đối của lớp thành phần. Mặc dù lớp bao có các thành phần đối tượng, nhưng trong lớp bao lại không được phép truy nhập đến các thuộc tính của các đối tượng này.

+ Trong các lớp thành phần, xây dựng sẵn các phương thức để có thể lấy ra các thuộc tính của lớp. + Trong lớp bao dùng các phương thức của lớp thành phần để nhận các thuộc tính của các đối tượng thành viên cần dùng đến.

Các ví dụ

Khi xây dựng phương thức của lớp bao cần sử dụng các phương thức của lớp thành phần. + Thành phần tĩnh là chung cho cả lớp, nó không phải là riêng của mỗi đối tượng. Vì vậy các câu lệnh in giá trị các thành phần này trong phương thức in là không logic.

Khi nào cần sử dụng các thành phần dữ liệu tĩnh

Các thuộc tính tenhang và tienban là riêng của mỗi hoá đơn, nên chúng được chọn là các thuộc tính thông thường. Còn các thuộc tính tshd và tstienban là chung cho cả lớp nên chúng được chọn là các thuộc tính tĩnh.

Ví dụ minh hoạ việc dùng phương thức tĩnh

Sử dụng hàm tạo để tạo ra các hoá đơn, dùng hàm huỷ để bỏ đi (loại đi) các hoá đơn không cần lưu trữ, dùng một phương thức để sửa chữa nội dung hoá đơn (nhập lại tiền bán). Vấn đề đặt ra là sau một số thao tác: Tạo, sửa và huỷ hoá đơn thì tổng số hoá đơn còn lại là bao nhiêu và tổng số tiền trên các hoá đơn còn lại là bao nhiêu?. Câu lệnh khai báo mảng sẽ gọi tới hàm tạo không đối để tạo các phần tử mảng.

Trong ví dụ trên, hàm tạo được gọi 30 lần để tạo 30 phần tử mảng đối tượng.

Ví dụ

Có thể dùng new và tên lớp để cấp phát một vùng nhớ cho một hoặc một dẫy các đối tượng. + Giả sử con trỏ q trỏ tới địa chỉ đầu vùng nhớ của một dẫy đối tượng.

Danh sách móc nối

Phương thức trả về 1 nếu họ tên nhập vào khác trống, trả về 0 nếu trái lại. + Cũng giống như các phần tử dữ liệu khác, một đối tượng có thể được khai báo là hằng bằng cách dùng từ khoá const. + Các phương thức có thể sử dụng cho các đối tượng hằng là hàm tạo và hàm huỷ.

Về lý thuyết các đối tượng hằng không thể bị thay đổi, mà chỉ được tạo ra hoặc huỷ bỏ đi. Tuy nhiên, chương trình EXE vẫn được tạo và khi thực hiện chương trình, thì nội dung các đối tượng hằng vẫn bị thay đổi. Phương thức toán tử ++ vẫn có thể làm thay đổi đối tượng hằng (mặc dù khi biên dịch có 3 cảnh báo).

Để biến một phương thức thành const ta chỉ việc viết thêm từ khoá const vào sau dòng đầu của phương thức. Chú ý: Nếu phương thức được khai báo bên trong và định nghĩa bên ngoài lớp, thì từ khoá const cần được bổ sung cả trong khai báo và định nghĩa phương thức. Trong thân phương thức const không cho phép làm thay đổi các thuộc tính của lớp.

Vị vậy việc dùng phương thức const cho các đối tượng hằng sẽ đảm bảo giữ nguyên nội dung của các đối tượng hằng. Ví dụ sau về lớp PS (phân số) minh hoạ việc dùng phương thức const. Hàm bạn (xem mục §6, chương 3) của một lớp, tuy không phải là phương thức của lớp, nhưng có thể truy nhập đến các thành phần riêng (private) của lớp.