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_castkhô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.