Nạp chồng toán tử và Nạp chồng hàm trong C++

C++ cho phép bạn xác định nhiều hơn một định nghĩa cho một tên hàm hoặc một toán tử trong cùng phạm vi (scope), được gọi tương ứng là Nạp chồng hàm (function overloading) và Nạp chồng toán tử (operator overloading) trong C++.

Một khai báo nạp chồng là một khai báo mà đã được khai báo với cùng tên như một khai báo được khai báo trước đó trong cùng phạm vi, ngoại trừ rằng: cả hai khai báo có các tham số khác nhau và định nghĩa khác nhau.

Khi bạn gọi một hàm nạp chồng hoặc một toán tử nạp chồng, thì compiler quyết định định nghĩa thích hợp nhất để sử dụng bằng việc so sánh các kiểu tham số bạn đã sử dụng để gọi hàm hoặc toán tử với các kiểu tham số đã được xác định trong các định nghĩa. Tiến trình lựa chọn hàm nạp chồng hoặc toán tử nạp chồng thích hợp nhất này được gọi là overload resolution - phân giải nạp chồng.

Nạp chồng hàm trong C++

Bạn có thể có nhiều định nghĩa cho cùng tên hàm trong cùng phạm vi. Định nghĩa của hàm phải khác lẫn nhau về kiểu và/hoặc số tham số trong danh sách tham số. Bạn không thể nạp chồng các khai báo hàm mà chỉ khác nhau ở kiểu trả về.

Trong ví dụ sau, cùng một hàm hamIn được sử dụng để in các kiểu dữ liệu khác nhau:

#include <iostream>
using namespace std;


class inDuLieu 
{
   public:
      void hamIn(int i) {
        cout << "In so nguyen: " << i << endl;
      }


      void hamIn(double  f) {
        cout << "In so thuc: " << f << endl;
      }


      void hamIn(char* c) {
        cout << "In ky tu: " << c << endl;
      }
};


int main(void)
{
   inDuLieu idl;


   // Goi ham hamIn de in so nguyen
   idl.hamIn(12345);
   // Goi ham hamIn de in so thuc
   idl.hamIn(6677.02);
   // Goi ham hamIn de in ky tu
   idl.hamIn("Hoc C++ co ban va nang cao tai hoc.tv");


   return 0;
}

Biên dịch và chạy chương trình C++ trên sẽ cho kết quả sau:

Nạp chồng toán tử trong C++

Bạn có thể định nghĩa lại hoặc nạp chồng hầu hết các toán tử có sẵn trong C++. Vì thế, một lập trình viên có thể sử dụng các toán tử với kiểu tự định nghĩa (user-defined).

Nạp chồng toán tử trong C++ là các hàm với tên đặc biệt: Tên hàm là từ khóa operator theo sau là ký hiệu của toán tử đang được định nghĩa. Giống như bất kỳ hàm khác, một toán tử nạp chồng có một kiểu trả về và một danh sách tham số.

Box operator+(const Box&);

Khai báo toán tử + để cộng hai đối tượng Box và trả về đối tượng Box cuối cùng. Hầu hết toán tử nạp chồng có thể được định nghĩa dưới dạng: các hàm không có thành viên (non-member) hoặc các hàm thành viên lớp. Trong trường hợp trên, chúng ta định nghĩa hàm ở dạng non-member của một lớp, thì sau đó chúng ta phải truyền hai tham số cho mỗi toán hạng, như sau:

Box operator+(const Box&, const Box&);

Ví dụ sau minh họa khái niệm nạp chồng toán tử bởi sử dụng một hàm thành viên. Ở đây, một đối tượng được truyền như là một tham số mà các thuộc tính của nó sẽ được truy cập bởi sử dụng đối tượng này, đối tượng mà sẽ gọi toán tử này có thể được truy cập bởi sử dụng toán tử this, như sau:

#include <iostream>
using namespace std;


class Box
{
   public:


      double tinhTheTich(void)
      {
         return chieudai * chieurong * chieucao;
      }
      void setChieuDai( double dai )
      {
          chieudai = dai;
      }


      void setChieuRong( double rong )
      {
          chieurong = rong;
      }


      void setChieuCao( double cao )
      {
          chieucao = cao;
      }
      // Nap chong toa tu + de cong hai doi tuong Box.
      Box operator+(const Box& b)
      {
         Box box;
         box.chieudai = this->chieudai + b.chieudai;
         box.chieurong = this->chieurong + b.chieurong;
         box.chieucao = this->chieucao + b.chieucao;
         return box;
      }
   private:
      double chieudai;      // chieu dai cua mot box
      double chieurong;     // Chieu rong cua mot box
      double chieucao;      // Chieu cao cua mot box
};
// ham main cua chuong trinh
int main( )
{
   Box Box1;                // Khai bao Box1 la cua kieu Box
   Box Box2;                // Khai bao Box2 la cua kieu Box
   Box Box3;                // Khai bao Box3 la cua kieu Box
   double thetich = 0.0;     // Luu giu the tich cua mot box tai day


   // thong tin chi tiet cua box 1
   Box1.setChieuDai(2.0); 
   Box1.setChieuRong(3.0); 
   Box1.setChieuCao(4.0);


   // thong tin chi tiet cua box 2
   Box2.setChieuDai(5.0); 
   Box2.setChieuRong(6.0); 
   Box2.setChieuCao(7.0);


   // the tich cua box 1
   thetich = Box1.tinhTheTich();
   cout << "The tich cua Box1 la: " << thetich <<endl;


   // the tich cua box 2
   thetich = Box2.tinhTheTich();
   cout << "The tich cua Box2 la: " << thetich <<endl;


   // cong hai doi tuong nhu sau:
   Box3 = Box1 + Box2;


   // the tich cua box 3
   thetich = Box3.tinhTheTich();
   cout << "The tich cua Box3 la: " << thetich <<endl;


   return 0;
}

Biên dịch và chạy chương trình C++ trên sẽ cho kết quả sau:

Toán tử có thể nạp chồng và không thể nạp chồng trong C++

Bảng dưới liệt kê danh sách các toán tử có thể được nạp chồng trong C++:

+-*/%^
&|~!,=
<><=>=++--
<<>>==!=&&||
+=-=/=%=^=&=
|=*=<<=>>=[]()
->->*newnew []deletedelete []

Còn đây là danh sách các toán tử không thể được nạp chồng trong C++:

::.*.?:

Ví dụ về Nạp chồng toán tử trong C++

Dưới đây là các ví dụ đa dạng minh họa Nạp chồng toán tử trong C++, từ đó giúp bạn hiểu sâu hơn về khái niệm này. Bạn click vào link để thấy ví dụ:

STTToán tử và Ví dụ
1Nạp chồng toán tử một ngôi (unary) trong C++
2Nạp chồng toán tử nhị phân trong C++
3Nạp chồng toán tử quan hệ trong C++
4Nạp chồng toán tử Input/Output trong C++
5Nạp chồng toán tử ++ và -- trong C++
6Nạp chồng toán tử gán trong C++
7Nạp chồng toán tử gọi hàm () trong C++
8Nạp chồng toán tử [] trong C++
9Nạp chồng toán tử truy cập thành viên lớp -> trong C++

Bình luận