Constructor – Hàm tạo trong C++

Hàm tạo là một phương thức của lớp, dùng để tạo dựng một đối tượng mới. Chương trình dịch sẽ cấp phát 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 số công việc khác nhằm chuẩn bị cho đối tượng mới.

* 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 báo để tạo ra một đối tượng đồng thời khởi gán cho các thuộc tính của đối tượng được tạo. Dựa vào các tham số trong khai báo mà trình biên dịch sẽ gọi đến hàm tạo nào.

+ Khi khai báo một biến đối tượng có thể sử dụng các tham số để 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ố để khởi gán.

+ 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.

+ 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 lần.

* Dùng hàm tạo trong cấp phát bộ nhớ:

+ Khi cấp phát bộ nhớ cho một đối tượng có thể dùng các tham số để khởi gán cho các thuộc tính của đối tương:

DIEM *x = new DIEM[10, 20];

+ Khi cấp phát bộ nhớ cho một dãy đối tượng, không được phép dùng tham số để khới gán.

* Dùng hàm tạo để biểu diễn các đối tượng hằng

Constructor là loại hàm đặc biệt của một lớp mà chúng thưc thi khi một đối tượng của lớp đươc khởi tạo. Constructor thường được sử dụng để khởi tao biến thành viên của một class để gán giá trị mặc định cho biến đó hoặc cung cấp cho người dùng một cách dể dàng để gán lại giá trị cho các biến thành viên của đối tượng đó.

Không giống như những hàm bình thường, constructor có một quy tắc đặc biệt để đặt tên cho chúng

  1. Tên của constructor phải luôn luôn giống như tên của lớp
  2. Constructor không có loại giá trị trả về (thậm chí không có void )

Môt constructor không có tham số thì gọi là default constructor .

Dưới đây là ví dụ minh họa về class có default constructor :

class Fraction

{

private:

     int m_nNumerator;

     int m_nDenominator;

public:

     Fraction() // default constructor

     {

         m_nNumerator = 0;

         m_nDenominator = 1;

     }

     int GetNumerator() { return m_nNumerator; }

     int GetDenominator() { return m_nDenominator; }

     double GetFraction() { return static_cast(m_nNumerator) / m_nDenominator; }

};

Class này được thiết kế để giữ giá trị tử số và mẫu số (có kiểu int). Chúng ta định nghĩa hàm default constructor có tên là Fraction (giống tên với tên của class theo đúng quy tắc). Khi chúng ta tạo một thể hiện (instance) của lớp Fraction, hàm default constructor này sẻ được gọi ngay khi được cấp phát bộ nhớ, và đối tượng của chúng ta sẻ được khởi tạo. Ví dụ với Class ở trên khi chúng ta thực thi đoạn lệnh dưới đây :

Fraction cDefault; // ham Fraction() sẻ duoc goi

std::cout << cDefault.GetNumerator() << “/” << cDefault.GetDenominator() << std::endl;

Giá trị output :

0/1

Chú ý rằng, numerator và denominator được khởi tạo với giá trị đã được gán cho chúng trong default constructor. Nếu không có default constructor, giá trị của numerator và denominator sẻ mang giá trị rác cho đến khi chúng ta gán giá trị cho chúng.

Constructor có Tham Số

Trong khi default constructor là một cách tốt để đảm báo đối tượng của class có giá trị khởi tạo khi sử dụng. Thỉnh thoảng chúng ta muốn một thể hiển (instances) của lớp chúng ta có một giá trị khác theo đúng mong muốn của mình. May mắn là constructor cũng có thể khai báo với tham số. Dưới đây là ví dụ về constructor có hai tham số kiểu int mà chúng ta sử dụng để khởi tạo cho numerator và denominator :

#include

class Fraction

{

private:

     int m_nNumerator;

     int m_nDenominator;

public:

     Fraction() // default constructor

     {

         m_nNumerator = 0;

         m_nDenominator = 1;

     }

     // Constructor with parameters

     Fraction(int nNumerator, int nDenominator=1)

     {

         assert(nDenominator != 0);

         m_nNumerator = nNumerator;

         m_nDenominator = nDenominator;

     }

     int GetNumerator() { return m_nNumerator; }

     int GetDenominator() { return m_nDenominator; }

     double GetFraction() { return static_cast(m_nNumerator) / m_nDenominator; }

};

Chú ý rằng, trong trường hợp này chúng ta có 2 hàm constructor : default constructor sẻ gọi trong trường hợp mặc định và constructor thứ hai sẻ gọi với hai đối số đầu vào. Cả hai constructor sẻ cùng tồn tại một cách yên bình trong class giống như trong overload hàm. Do đó, bạn có thể định nghĩa nhiều constructor nếu bạn muốn, miễn là mỗi constructor có tham số khác nhau (loại hoặc số tham số đầu vào).

Chúng ta có thể sử dụng constructor với tham số như thế nào ? ví dụ :

Fraction cFiveThirds(5,3); // goi constructor Fraction(int, int)

Đây là một fraction cụ thể được khỏi tạo giá trị là 5/3.

Chú ý rằng, chúng ta có thể sử dụng giá trị mặc định của tham số thứ 2 của constructor có tham số ở trên, câu gọi hàm dưới đây là được phép

Fraction six(6); // constructor Fraction (int, int) được gọi

Lúc này phân số six có giá trị là 6/1 .

Trong trường hợp này, default constructor thực sự không cần thiết. Chúng ta có thể bỏ nó đi bằng cách xây dụng một constructor với tham số có khởi tạo giá trị :

#include

class Fraction

{

private:

     int m_nNumerator;

     int m_nDenominator;

public:

     // Default constructor

     Fraction(int nNumerator=0, int nDenominator=1)

     {

          assert(nDenominator != 0);

          m_nNumerator = nNumerator;

          m_nDenominator = nDenominator;

     }

     int GetNumerator() { return m_nNumerator; }

     int GetDenominator() { return m_nDenominator; }

     double GetFraction() { return static_cast(m_nNumerator) / m_nDenominator; }

};

Với cách xây dựng constructor như trên chúng ta đã định nghĩa được một constructor có có default và constructor có tham số :

Fraction cDefault; // sẻ gọi Fraction(0, 1)

Fraction cSix(6); // sẻ goi Fraction(6, 1)

Fraction cFiveThirds(5,3); // sẻ goi Fraction(5,3)

Một Lớp không có Default Constructor 

Điều gì sẻ xảy ra nếu một lớp không được khai báo default constructor . Câu trả lời là C++ sẻ cấp phát một vùng nhớ cho mỗi thể hiện (instance) của một lớp, nhưng sẻ không khỏi tạo giá trị cho các biến thành viên của lớp đó. Ví dụ :

class Date

{

private:

     int m_nMonth;

     int m_nDay;

     int m_nYear;

};

int main()

{

     Date cDate;

     // cac bien thanh vien cua cDate chua gia tri rác

     // Nêu gia tri cua bien thanh vien duoc lay luc nay se nhu the nao

     return 0;

}

Trong chương trình ví dụ ở trên, bởi vì chúng ta khai báo lớp Date, nhưng không có constructor, khi chúng ta khai báo một đối tượng thuộc lớp Date

Các biến thành viên m_nMonth, m_nDay, and m_nYear của lớp đó sẽ không được khỏi tạo. Do đó, chúng sẽ có giá trị rác. Đây là ý lí do tại tao cung cấp default constructor khi bao báo class là một việc làm tốt.

Những chia sẻ trên hi vọng sẽ giúp các bạn hiểu rõ hơn về Constructor – hàm tạo trong C++.

Ngoài ra, để bạn có thể tìm hiểu thông tin về lập trình viên, về khóa học giúp bạn trở thành những lập trình viên chuyên nghiệp tại www.stanford.com.vn.

 

Constructor – Hàm tạo trong C++
5 (100%) 11 votes

Add Comment