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

Template is_polymorphic trong C++ STL

std::is_polymorphic (header <type_traits>) kiểm tra xem một kiểu T có phải là lớp đa hình (polymorphic class) hay không. Lớp đa hình là lớp có ít nhất một hàm ảo (virtual function).

Cú pháp

template <class T> struct is_polymorphic;

Kết quả: is_polymorphic<T>::value (bool) hoặc is_polymorphic_v<T> (C++17).

Định nghĩa lớp đa hình

Lớp có ít nhất một hàm ảo (kể cả kế thừa từ lớp cơ sở có hàm ảo).

class Base {
    virtual void foo() {} // Có virtual function → Base là polymorphic
};

class Derived : public Base {}; // Kế thừa virtual → Derived cũng polymorphic

class NonPoly {
    void bar() {} // Không virtual → không polymorphic
};

Ví dụ kiểm tra

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

struct TP {
    virtual void display(); // Có virtual
};

struct TP_2 : TP {}; // Kế thừa từ TP

class TP_3 {
    virtual void display() = 0; // Pure virtual → abstract, cũng là polymorphic
};

struct TP_4 : TP_3 {}; // Kế thừa

struct NonPoly {
    int var;
};

int main() {
    cout << boolalpha;
    cout << "Kiểm tra is_polymorphic:\n";
    cout << "TP (có virtual):       " << is_polymorphic<TP>::value << '\n';       // true
    cout << "TP_2 (kế thừa TP):     " << is_polymorphic<TP_2>::value << '\n';     // true
    cout << "TP_3 (pure virtual):   " << is_polymorphic<TP_3>::value << '\n';   // true
    cout << "TP_4 (kế thừa TP_3):   " << is_polymorphic<TP_4>::value << '\n';   // true
    cout << "NonPoly (không virtual): " << is_polymorphic<NonPoly>::value << '\n'; // false
    
    // Kiểu cơ bản
    cout << "int: " << is_polymorphic<int>::value << '\n'; // false
    cout << "void: " << is_polymorphic<void>::value << '\n'; // false
    
    return 0;
}

Đầu ra

Kiểm tra is_polymorphic:
TP (có virtual):       true
TP_2 (kế thừa TP):     true
TP_3 (pure virtual):   true
TP_4 (kế thừa TP_3):   true
NonPoly (không virtual): false
int: false
void: false

Ví dụ 2: Lớp cơ sở không virtual, lớp dẫn xuất có virtual

struct Base { int x; };           // Không polymorphic
struct Derived : Base {           // Không polymorphic (Base không có virtual)
    virtual void foo();           // Nhưng Derived có virtual!
};

int main() {
    cout << boolalpha;
    cout << "Base: " << is_polymorphic<Base>::value << '\n';     // false
    cout << "Derived: " << is_polymorphic<Derived>::value << '\n'; // true
    return 0;
}

Ứng dụng

  • Kiểm tra có thể dùng dynamic_cast không (chỉ hoạt động với kiểu đa hình).
  • Template metaprogramming: chọn thuật toán tối ưu cho kiểu đa hình vs không đa hình.
  • Serialization: xử lý khác nhau cho đối tượng có v-table.

Lưu ý

  • Lớp trừu tượng (abstract class - có pure virtual function) luôn là polymorphic.
  • Union không thể là polymorphic (không cho phép virtual function).
  • Kiểu cơ bản (int, float, con trỏ...) luôn false.