[OOP] Các dạng nạp chồng toán tử

Như chúng ta đã biết một hàm trong C++ có thể khai báo và định nghĩa chúng:

  • Trực thuộc 1 class (member function)
  • Bạn của 1 class (friend function)
  • Không thuộc class nào (nomal function)

Trong bài giới thiệu về nạp chồng toán tử chúng ta đã biết toán tử hoạt động giống như 1 hàm. Vì vậy ta cũng có thể nạp chồng toán tử theo các dạng sau.

  1. Nạp chồng toán tử sử dụng member function
  2. Nạp chồng toán tử sử dụng friend function
  3. Nạp chồng toán tử sử dụng nomal function

Dưới đây ta sẽ đi tìm hiểu lần lượt từng dạng khi nạp chồng toán tử

1. Nạp chồng toán tử sử dụng member function

Ta định nghĩa hàm toán tử thuộc 1 class.

Nạp chồng toán tử sử dụng member function có 1 số điểm chú ý sau.

  • Toán hạng đầu tiên bên trái là tham số ngầm định của hàm (con trỏ this)
  • Các toán hạng còn lại là tham số của hàm toán tử.

Xem lại bài viết về con trỏ this

Ví dụ:


#include <iostream>

#include <string>

using namespace std;

class PS

{

private:

   int tu;

   int mau;

public:

   PS(int tu, int mau)

   {

      this->tu = tu;

      this->mau = mau;

   }

   string ToString()

   {

      return to_string(tu) + "/" + to_string(mau);

   }

   //Nạp chồng toán tử + giữa 2 phân số
   PS& operator+(PS& ps)

   {

      PS res(0, 0);

      res.tu = this->tu * ps.mau + this->mau * ps.tu;

      res.mau = this->mau * ps.mau;

      return res;

   }

};

int main()

{

   PS p1(3, 4);

   PS p2(4, 5);

   PS result = p1 + p2;

   cout << p1.ToString() << " + " << p2.ToString() << " = " << result.ToString() << endl;

   return 0;

}

Kết quả:

3/4 + 4/5 = 31/20

Trong ví dụ trên ta nạp chồng toán tử ‘+’ cho 2 phân số.

PS& operator+(PS& ps)

Toán tử + có 2 toán hạng nhưng ở đây hàm toán tử ta chỉ định nghĩa 1 tham số, vì toán hạng thứ nhất là tham số mặc định (con trỏ this).

Hàm nạp chồng toán tử ở trên ta chỉ thực hiện được phép ‘+’ 2 phân số. Nếu ta muốn thực hiện phép ‘+’ giữa phân số và 1 kiểu dữ liệu khác ta phải nạp chồng tiếp hàm toán tử tương ứng.

 PS& operator+(type val) // ps + val

Chú ý:

Vì nạp chồng toán tử sử dụng member function thì toán hạng đầu tiên bên trái là tham số ngầm định (con trỏ this) nên ta không thể nạp chồng toán tử sử dụng member function mà toán hạng đầu tiên có kiểu dữ liệu khác.

Ví dụ:

int + ps; => Không thể nạp chồng 1 số kiểu int + ps sử dụng member function.

2. Nạp chồng toán tử sử dụng friend function.

Friend function là hàm không thuộc class nhưng có thể truy cập được các phần tử private của class.

Xem lại bài viết về friend function trong C++

Vì hàm bạn không có tham số ngầm định (this) nên số tham số của hàm bạn toán tử phải bằng với số toán hạng của toán tử.

Thứ tự các tham số trùng với thứ tự toán hạng của toán tử.

Ví dụ:


class PS

{

private:

   int tu;

   int mau;

   public:

   PS(int tu, int mau)

   {

      this->tu = tu;

      this->mau = mau;

   }

   //Nạp chồng toán tử + giữa 2 phân số
   friend PS& operator+(PS& ps1, PS& ps2)

   {

      PS res(0, 0);

      res.tu = ps1.tu * ps2.mau + ps1.mau * ps2.tu;

      res.mau = ps1.mau * ps2.mau;

      return res;

   }

   //Nạp chồng toán tử + giữa số nguyên và phân số (int + ps)
   friend PS& operator+(int val, PS& ps)

   {

      PS res(0, 0);

      res.tu = val * ps.mau + ps.tu;

      res.mau = ps.mau;

      return res;

   }

   //Nạp chồng toán tử + giữa phân số và số nguyên (ps + int)
   friend PS& operator+(PS& ps, int val)
 
   {

      PS res(0, 0);

      res.tu = val * ps.mau + ps.tu;

      res.mau = ps.mau;

      return res;

   }

};

3. Nạp chồng toán tử sử dụng nomal function

Nomal function là hàm không thuộc class và cũng thể truy cập được các thành phần private của class.

Nạp chồng toán tử sử dụng nomal function cũng gần giống với sử dụng function chỉ khác ta phải truy cập các biến thành viên private của class thông qua các hàm public.

Ví dụ:


#include <iostream>

#include <string>

using namespace std;

class PS

{

private:

   int tu;

   int mau;

public:

   PS(int tu, int mau)

   {

      this->tu = tu;

      this->mau = mau;

   }

   int GetTu() const

   {

      return tu;

   }

   void SetTu(int val)

   {

      this->tu = val;

   }

   int GetMau() const

   {

      return mau;

   }

   void SetMau(int val)
  
   {

      this->mau = val;

   }

   string ToString()

   {

      return to_string(tu) + "/" + to_string(mau);

   }

};

//Nạp chồng toán tử + dùng nomal function
PS& operator+(PS& ps1, PS& ps2)

{

   PS res(0, 0);

   res.SetTu (ps1.GetTu() * ps2.GetMau() + ps1.GetMau() * ps2.GetTu());

   res.SetMau (ps1.GetMau() * ps2.GetMau());

   return res;

}

int main()

{

   PS p1(3, 4);

   PS p2(4, 5);
  
   PS result = p1 + p2;

   cout << p1.ToString() << " + " << p2.ToString() << " = " << result.ToString() << endl;

   return 0;

}

Kết quả:

3/4 + 4/5 = 31/20

Đến đây ta đã cơ bản hiểu về các dạng khi nạp chồng toán tử. Tuy nhiên ta sẽ đặt ra câu hỏi.

Khi nào thì ta sử dụng nạp chồng toán tử dùng member function, friend function hay nomal function?

Chúng ta sẽ trả lời cho câu hỏi trên trong bài tiếp theo!

Was this article helpful?

Có 1 bình luận

  1. Đức

    tại sao phải có dấu ‘&’ ở ngay hàm PS& operator+ (PS&) vậy ad, theo như mình thấy thì nó trả về 1 biến khác mà đâu có thay đổi đến giá trị của tử và mẫu đâu mà sài dấu ‘&’ vậy ???

Leave A Comment?