0

Interfaces in C++ (Pure virtual functions)

I. Giải thích về Interface

Interface sẽ đưa ra những quy định mà đối tượng (hoặc lớp) cần có, tức là nó chỉ định "phải có những chức năng nào" mà không nói rõ "cách thực hiện những chức năng đó" như thế nào. Các lớp triển khai interface sẽ tự định nghĩa cách cài đặt chi tiết cho những chức năng đó.

Để dễ hiểu hơn thì thông qua một ví dụ có class robot: class này sẽ có những method bắt buộc như: start, stop, left, right. Khi ta tạo robot A có 2 chân và robot B có 4 chân thì những method này sẽ thực hiện theo những cách khác nhau chứ không thể nào mà giống nhau được. Nhưng 2 robot này “bắt buộc” phải có 4 method này.

Interface trong c++ được triển khai bởi sử dụng các lớp trừu tượng (Abstract class)

II. Pure Virtual Function

1. Khái niệm

Một hàm được khai báo ở class base nhưng không có thân hàm. Có cú pháp: virtual void func() = 0

  • Đóng vai trò như một bản thiết kế mà mọi class devired phải tuân theo.
  • Không thể tạo một object từ một class có chứa Pure Virtual Function (hàm ảo thuần túy). Class này được gọi là Abstract Class.
  • Bất kì class devired muốn tạo được object thì phải override toàn bộ hàm ảo thuần túy của class base.

2. Ví dụ

#include <iostream>
#include <string>
#include <map>

using namespace std;

// Abstract Class
class CacheStorage {
 public:
   // Hàm ảo thuần túy
   virtual void write(void) = 0;
   virtual void read(void) = 0;
   
   virtual ~CacheStorage() {}
};

// Derived class
class MemoryCache : public CacheStorage {
 public:
   void write(void) override {
     std::cout << "[RAM] Đang ghi vào bộ nhớ đệm ..." << std::endl;
   }
   
   void read(void) override {
     std::cout << "[RAM] Đang đọc từ bộ nhớ đệm ..." << std::endl;
   }
};

class DiskCache : public CacheStorage {
 public:
   void write(void) override {
     std::cout << "[DISK] Đang ghi vào disk..." << std::endl;
   }
   
   void read(void) override {
     std::cout << "[DISK] Đang đọc từ disk.." << std::endl;
   }
};

int main() 
{
   // CacheStorage Init_my_cache; Don't create object from Abstract class
   
   CacheStorage* myCache;
   
   myCache = new MemoryCache;
   myCache->write();
   myCache->read();
   
   myCache = new DiskCache;
   myCache->write();
   myCache->read();
   
   
   delete myCache;
   return 0;
}

Tại sao lại có virtual destructor. Hãy xem một trường hợp sau

  • Class MemoryCache có một buffer được cấp phát: char *buffer = new ...
  • Dùng con trỏ class base để quản lí: CacheStorage* ptr = new MemoryCache();

Trả lời

  • Nếu không có virtual thì khi ta delete ptr thì nó chỉ gọi Destructor của class base. Từ đó dẫn đến Destructor của class MemoryCache không được chạy và buffer không được giải phóng sẽ bị memory leak.
  • Nếu có virtual thì Destructor của class base sẽ thực hiện tìm kiếm ngược. Nó sẽ gọi hàm hủy của các class derived trước khi gọi hàm hủy của class base.

Ví dụ:



All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí