Hàm khởi tạo là gì

Trong bài viết này chúng ta sẽ tìm hiểu về hàm khởi tạo (constructor) và hàm hủy (destructor) trong lập trình hướng đối tượng.

Hàm khởi tạo là gì
Hàm khởi tạo (constructor) và hàm hủy (destructor)

1. Hàm khởi tạo (constructor)

Một constructor cho phép bạn khởi tạo các thuộc tính của đối tượng khi tạo đối tượng.
Nếu bạn tạo một function __construct(), PHP sẽ tự động gọi function này khi bạn tạo một object từ một class.
Lưu ý hàm construct thì được bắt đầu với 2 dấu gạch dưới.

Chúng ta xem ví dụ bên dưới, chúng ta có thể sử dụng hàm khởi tạo để khởi tạo giá trị cho các thuộc tính, do đó làm giảm số lượng dòng code mà ta phải viết:

name = $name; $this->color = $color; } function get_name() { return $this->name; } function get_color() { return $this->color; } } $buffalo = new Animal("Buffalo", "red"); echo $buffalo->get_name(); echo "
"; echo $buffalo->get_color(); ?>

Lưu ý, nếu một class A kế thừa từ class B, nếu không định nghĩa hàm khởi tạo nó sẽ lấy hàm khởi tạo của class cha (class B). Và để gọi hàm khởi tạo của class cha, ta sử dụng parent::__construct().

2. Hàm hủy (destructor)

Một hàm hủy được gọi khi đối tượng bị hủy hoặc tập lệnh bị dừng hoặc thoát. Nếu bạn tạo một hàm __destruct(), PHP sẽ tự động gọi hàm này ở cuối tập lệnh.
Lưu ý, function __destruct() được bắt đầu với 2 dấu gạch chân.

Ví dụ bên dưới có một hàm __construct() được tự động gọi khi bạn tạo một đối tượng từ một class và một hàm __destruct () được gọi tự động ở cuối tập lệnh.

name = $name; } function __destruct() { echo "The buffalo is {$this->name}."; } } $buffalo = new Animal("Con trâu"); ?>

Cũng giống như hàm khởi tạo, Nếu một class B kế thừa từ class A, nếu class B không khai báo hàm hủy thì nó sẽ được kế thừa hàm hủy của class A. Trường hợp để gọi hàm hủy của class cha, chúng ta sử dụng parent::__destruct().

3. Kết luận

Trong bài viết này chúng ta đã tìm hiểu về hàm khởi tạo và hàm hủy trong OOP. Rất đơn giản đúng không nào. Nếu có thắc mắc gì về bài viết, hãy để lại bình luận ngay bên dưới nhé.
Xem thêm:
– Lập trình hướng đối tượng là gì?
– 4 tính chất lập trình hướng đối tượng.
– class và object trong lập trình hướng đối tượng.

Bài viết tham khảo: https://www.w3schools.com/php/php_oop_constructor.asp

Chúng ta đã được biết về lớp, đối tượng và các cách xác định hàm ở bài trước. Trong bài này mình sẽ tìm hiểu về hàm khởi tạo và hàm hủy trong C++ là gì và khác gì so với các hàm thông thường nhé.

Bài viết sẽ sử dụng C++ là ngôn ngữ chính để giải thích và code minh họa cho OOP nên chúng ta cần hiểu rõ một đặc tính của C++ trong lập trình hướng đối tượng.

1. Hàm khởi tạo (Constructor):

Hàm khởi tạo (constructor) là một phương thức đặc biệt được gọi tự động tại thời điểm đối tượng được tạo. Mục đích của hàm khởi tạo là để khởi tạo các thành viên dữ liệu của đối tượng.

Một hàm khởi tạo sẽ khác những hàm thông thường ở những điểm sau:

  • Có tên trùng với tên lớp
  • Không có kiểu dữ liệu trả về ( kể cả kiểu void)
  • Tự động được gọi khi một đối tượng thuộc lớp được tạo ra
  • Nếu chúng ta không khai báo một hàm khởi tạo, trình biên dịch C++ sẽ tự động tạo một hàm khởi tạo mặc định cho chúng ta (sẽ là hàm ​​không có tham số nào và có phần thân trống).

Ví dụ ta có lớp Mayvitinh có 2 thuộc tính là chieudai và mausac, thì hàm khởi tạo có thể định nghĩa cho lớp Mayvitinh như sau:

class Mayvitinh{ int chieudai; string mausac; public: Mayvitinh(); // Đây là hàm khởi tạo Mayvitinh(int cd) { chieudai = cd; } Mayvitinh(string ms) { // Đây là hàm khởi tạo mausac = ms; } Mayvitinh(int cd, string ms) { // Đây là hàm khởi tạo chieudai = cd; mausac = ms; } };

Hàm khởi tạo về cơ bản sẽ được chia làm 3 loại:

  1. Hàm khởi tạo không tham số (Cũng có thể gọi là hàm tạo mặc định – Default Constructor)
  2. Hàm khởi tạo có tham số (Parameterized Constructor)
  3. Hàm khởi tạo sao chép (Copy Constructor)

1.1. Hàm khởi tạo không tham số (Default Constructor):

Mình lấy một ví dụ:

#include using namespace std; class Mayvitinh { public: Mayvitinh() { cout << "Ham khoi tao tu dong duoc goi." << endl; } }; int main() { Mayvitinh mayAsus; //khởi tạo đối tượng mayAsus Mayvitinh mayAcer; //khởi tạo đối tượng mayAcer return 0; }

Khi chạy chương trình ta sẽ có kết quả như sau:

Hàm khởi tạo là gì

Trong ví dụ trên, hàm tạo Mayvitinh() không hề có đối số nào được truyền vào. 

1.2. Hàm khởi tạo có tham số (Parameterized Constructor):

Với loại hàm tạo này ta có thể truyền đối số cho chúng. Thông thường, các đối số này giúp khởi tạo một đối tượng khi nó được tạo.

Để khai báo một hàm khởi tạo có tham số chỉ cần thêm các tham số vào nó giống như cách bạn thêm tham số bất kỳ hàm nào khác. Khi bạn xác định phần thân của hàm tạo, hãy sử dụng các tham số để khởi tạo đối tượng.

Chúng ta cùng xem xét một ví dụ đơn giản về hàm khởi tạo có tham số trong C++ như sau:

#include using namespace std; class Mayvitinh { int chieurong; int chieudai; string tenmay; public: Mayvitinh(int cd) { chieudai = cd; } Mayvitinh(int cd, string tm) { chieudai = cd; tenmay = tm; chieurong = 20; } Mayvitinh(int cd, string tm, int cr) { chieudai = cd; tenmay = tm; chieurong = cr; } void HienThi() { cout << tenmay << endl; cout << " Chieu dai: " << chieudai << endl; cout << " Chieu rong: " << chieurong << endl; } }; int main() { Mayvitinh mayAsus = Mayvitinh(50, "may Asus", 25); Mayvitinh mayAcer = Mayvitinh(45, "mau Acer"); Mayvitinh mayMac = Mayvitinh(30, "may Mac"); mayAsus.HienThi(); mayAcer.HienThi(); mayMac.HienThi(); return 0; }

Sau khi chạy chương trình ta sẽ có kết quả:

Hàm khởi tạo là gì

Lưu ý:

  • Khi một đối tượng được khai báo trong hàm khởi tạo có tham số, các giá trị ban đầu phải được truyền dưới dạng đối số cho hàm tạo.
  • Các hàm khởi tạo có thể được gọi một cách rõ ràng hoặc ngầm định.
Mayvitinh mayAcer = Mayvitinh("may Acer", 25); // Đây là cách rõ ràng Mayvitinh mayAcer("May Acer", 25); // Đây là cách ngầm định

Công dụng của hàm khởi tạo có tham số

  • Khởi tạo các thành phần dữ liệu khác nhau của các đối tượng khác nhau với các giá trị khác nhau khi chúng được tạo.
  • Nạp chồng các hàm khởi tạo. (Có thế các bạn chưa hiểu "nạp chồng" là gì phải không? Nói nôm na là ta sẽ có nhiều hơn một hàm khởi tạo trong cùng một lớp. Mình sẽ giải thích rõ hơn về vấn đề này ở bài sau, các bạn nhớ đón xem nhé.)

1.3. Hàm khởi tạo sao chép (Copy Constructor):

Hàm khởi tạo sao chép (Copy Constructor) là một hàm xây dựng được sử dụng để khai báo và khởi tạo một đối tượng từ một đối tượng khác.

Cú pháp của hàm khởi tạo sao chép (Copy Constructor) như sau:

ClassName(const ClassName &old_obj){ // Code }

Trong đó Classname là tên của lớp, old_obj là đối tượng cũ sẽ lấy làm gốc để sao chép sang đối tượng mới.

Chúng ta lấy ví dụ đơn giản về hàm khởi tạo sao chép nhé:

#include using namespace std; class Mayvitinh { int chieurong; int chieudai; string tenmay; public: Mayvitinh(int cd, string tm, int cr) { chieudai = cd; tenmay = tm; chieurong = cr; } Mayvitinh(Mayvitinh &m) { tenmay = m.tenmay; chieudai = m.chieudai; chieurong = m.chieurong; } void HienThi() { cout << tenmay << endl; cout << " Chieu dai: " << chieudai << endl; cout << " Chieu rong: " << chieurong << endl; } }; int main() { Mayvitinh mayAsus(50, "may Asus", 25); Mayvitinh mayAcer(mayAsus); mayAsus.HienThi(); mayAcer.HienThi(); return 0; }

Và kết quả sau khi thực thi chương trình trên như sau:

Hàm khởi tạo là gì

Hàm khởi tạo sao chép (Copy Constructor) được gọi trong các trường hợp sau đây:

  • Khi một đối tượng của lớp được trả về bằng một giá trị.
  • Khi một đối tượng của lớp được truyền đối số dưới dạng tham số của một hàm.
  • Khi một đối tượng được tạo ra dựa trên một đối tượng khác cùng lớp.

Ví dụ: Mayvitinh mayAcer = mayAsus

  • Khi trình biên dịch tạo một đối tượng tạm thời.

Lưu ý:

Bất cứ khi nào chúng ta định nghĩa một hoặc nhiều hàm tạo có tham số cho một lớp, hàm tạo mặc định (không có tham số) cũng phải được xác định rõ ràng vì trình biên dịch sẽ không cung cấp hàm tạo mặc định trong trường hợp này. Điều đó tuy không cần thiết nhưng nó được coi là cách tốt nhất để luôn xác định một hàm tạo mặc định.

2. Hàm hủy (Desconstructor):

Hàm hủy (Destructor) ngược lại với hàm khởi tạo, trong khi hàm khởi tạo dùng để khởi tạo giá trị cho đối tượng thì hàm hủy dùng để hủy đối tượng.

Chỉ có duy nhất một hàm hủy trong một lớp. Hàm hủy tự động được gọi. Nếu như chúng ta không định nghĩa hàm hủy thì mặc định trình biên dịch sẽ tự tạo ra một hàm hủy mặc nhiên.

Cũng giống như hàm xây dựng, hàm hủy được định nghĩa có cùng tên với tên lớp, khôn có bất cứ kiểu gì trả về kể cẳ kiểu void, tuy nhiên phải có dấu ~ trước tên của hàm hủy.

Cú pháp của hàm hủy (Destructor) như sau:

~Classname() { };

Chúng ta cùng xem xét một ví dụ đơn giản nhất về hàm hủy như sau:

#include using namespace std; class Mayvitinh { public: Mayvitinh() { cout << "Ham khoi tao duoc goi" << endl; } ~Mayvitinh() { cout << "Ham huy duoc goi" << endl; } }; int main() { Mayvitinh mayAsus; Mayvitinh mayAcer; return 0; }

Và sau khi chạy chương trình sẽ có kết quả như sau: 

Hàm khởi tạo là gì

Như trong code trên, ta có thể thấy hàm hủy (Destructor) sẽ được gọi tự động khi đối tượng đi ra khỏi phạm vi:

  • Kết thúc hàm
  • Kết thúc chương trình
  • Kết thúc một block
  • Toán tử delete được gọi

Và có hai hạn chế khi sử dụng hàm hủy đó là:

  • Chúng ta không thể lấy địa chỉ của nó
  • Lớp con không có thừa kế hàm hủy từ lớp cha của nó

Với C++ thì nếu ta không khai báo một hàm hủy, trình biên dịch cũng sẽ tự định nghĩa một hàm hủy. Thông thường thì hàm hủy này hoạt động khá tốt, nhưng khi bài toán có sử dụng con trỏ, hoặc cấp phát bộ nhớ động thì ban nên khai báo một hàm huỷ riêng để tránh rỏ rỉ bộ nhớ.

Tạm kết

Như vậy là chúng ta đã tìm hiểu xong hàm khởi tạo (Constructor) và hàm hủy (Destructor), hai hàm này sẽ gắn liền xuyên suốt trong OOP.

Mình sẽ kết thúc bài này tại đây. Các bạn có thể rate và comment góp ý ở bên dưới nếu thấy bất cứ điều gì không chính xác để những bài sau tốt hơn.

Cảm ơn các bạn đã dành thời gian theo dõi.