[OOP] Hàm thuần ảo (pure virtual function) và abstract class.

Hàm thuần ảo (pure virtual) là dạng đặc biệt của virtual function, không có thân hàm. Hàm thuần ảo chỉ có khai báo nguyên mẫu hàm và được định nghĩa trong lớp dẫn suất.

Để khai báo hàm thuần ảo ta khai báo hàm ảo không có thân hàm và gán bằng 0.

Ví dụ:


class Base

{

public:

   //Hàm thuần ảo
   virtual void Info() = 0;

};

Khi sử dụng hàm thuần ảo ta chú ý 2 vấn đề:

  1. Lớp chứa ít nhất 1 hàm thuần ảo được gọi là lớp trừu tượng (abstract class) ta KHÔNG thể tạo đối tượng cho abstract class.
  2. Lớp dẫn suất từ lớp trừu tượng phải định nghĩa tất cả các hàm thuần ảo, nếu không lớp dẫn suất đó cũng trở thành abstract class.

Ví dụ:


#include <iostream>

using namespace std;

class Base

{

public:

   virtual void Info() = 0;

};

class  Derived : public Base

{

public :

   void Info() override

   {

      cout << "This function is defined by Derived class" << endl;

   }

};

int main()

{

   //Error-Không thể tạo đối tượng abstract class
   Base base;

   //Correct
   Base* pBase = new Derived();

   pBase->Info();

   delete pBase;

   return 0;

}

Trong C++ ta cũng có thể khai báo hàm thuần ảo có thân hàm. Tuy nhiên thân hàm không được định nghĩa bên trong class mà phải định nghĩa bên ngoài class.

Ví dụ:


class Base

{

public:

   virtual void Info() = 0;

};

void Base::Info()

{

   cout << "Base :: Info" << endl;

}

Trong ví dụ trên hàm Info là hàm thuần ảo, tuy nhiên ta có thể định nghĩa thân hàm bên ngoài class. Nó được sử dụng khi lớp cơ sở muốn cung cấp 1 định nghĩa mặc định cho hàm thuần ảo. Các lớp kế thừa từ nó vẫn phải định nghĩa lại hàm, tuy nhiên khi định nghĩa lại hàm lớp dẫn suất có thể sử dụng định nghĩa mặc định của lớp cơ sở đã cung cấp.

Ví dụ:


#include <iostream>

using namespace std;

class Base

{

public:

   virtual void Info() = 0;

};

//Định nghĩa thân hàm mặc định cho hàm thuần ảo
void Base::Info()

{

   cout << "Base :: Info" << endl;

}

class  Derived : public Base

{

public :

   void Info() override

   {

      Base::Info();

   }

};

int main()

{

   Base* pBase = new Derived();

   pBase->Info();

   delete pBase;

   return 0;

}

Kết quả:

Base :: Info

Was this article helpful?

Leave A Comment?