Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> C++

Template is_abstract trong C++ STL

std::is_abstract (header <type_traits>) kiểm tra xem một kiểu T có phải là lớp trừu tượng (abstract class) hay không. Lớp trừu tượng là lớp có ít nhất một hàm ảo thuần túy (pure virtual function).

Cú pháp

template <class T> struct is_abstract;

Định nghĩa lớp trừu tượng

class Abstract {
public:
    virtual void foo() = 0; // Pure virtual function
    virtual ~Abstract() = default;
};

class Concrete : public Abstract {
public:
    void foo() override {} // Implement pure virtual
}; // Concrete KHÔNG phải abstract

Ví dụ 1: Kiểm tra cơ bản

#include <iostream>
#include <type_traits>
using namespace std;

struct TP_1 { int var; };           // Không abstract
struct TP_2 { virtual void f() = 0; }; // Abstract (pure virtual)
class TP_3 : TP_2 { };              // Abstract (kế thừa pure virtual, không implement)

int main() {
    cout << boolalpha;
    cout << "Kiểm tra is_abstract:\n";
    cout << "TP_1 (có biến):        " << is_abstract<TP_1>::value << '\n'; // false
    cout << "TP_2 (pure virtual):   " << is_abstract<TP_2>::value << '\n'; // true
    cout << "TP_3 (kế thừa TP_2):   " << is_abstract<TP_3>::value << '\n'; // true
    return 0;
}

Đầu ra

Kiểm tra is_abstract:
TP_1 (có biến):        false
TP_2 (pure virtual):   true
TP_3 (kế thừa TP_2):   true

Ví dụ 2: Lớp trừu tượng vs lớp cụ thể

struct Interface {
    virtual void method() = 0;
    virtual ~Interface() = default;
};

class Impl : public Interface {
public:
    void method() override { cout << "Implemented\n"; }
};

int main() {
    cout << boolalpha;
    cout << "Interface: " << is_abstract<Interface>::value << '\n'; // true
    cout << "Impl:      " << is_abstract<Impl>::value << '\n';      // false
    
    // Không thể khởi tạo abstract class
    // Interface i; // LỖI biên dịch
    Impl impl; // OK
    impl.method();
    return 0;
}

Đầu ra

Interface: true
Impl:      false
Implemented

Đặc điểm quan trọng

  • Lớp có ít nhất một pure virtual function là abstract.
  • Kế thừa từ abstract class mà không implement tất cả pure virtual → lớp con cũng abstract.
  • Abstract class không thể khởi tạo đối tượng (instantiate).
  • Có thể dùng làm interface (chỉ chứa pure virtual).
  • Destructor ảo (virtual ~Base()) khuyến nghị cho base class polymorphic.

Mối quan hệ

is_abstract → is_polymorphic (luôn true nếu abstract)
is_polymorphic → KHÔNG nhất thiết abstract

Ứng dụng

  • Static assert ngăn chặn instantiate abstract class trong template.
  • Factory pattern: kiểm tra kiểu trả về có phải abstract không.
  • Plugin system: chỉ đăng ký class concrete (non-abstract).

Lưu ý

is_abstract chỉ hoạt động với kiểu lớp (class type). Với kiểu non-class (int, pointer...), luôn trả về false.