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.