Toán tử ‘typeid’ trong C++
Nếu như Java có typeof thì C++ có typeid. typeid là một toán tử một ngôi (unary operator) trong C++ dùng để lấy thông tin lúc runtime (Run-time Type Information- RTTI) về kiểu dữ liệu của một biểu thức hoặc của một kiểu dữ liệu cụ thể nào đó. typeid chỉ nhận một tham số duy nhất là một kiểu dữ liệu hoặc một expression.
1 2 3 |
typeid(type); // or typeid(expression); |
Giá trị trả về của typeid là một object kiểu ‘const std::type_info‘ được define trong file header <typeinfo>. Object trả về này có thể được dùng để so sánh ‘==’ hoặc ‘!=’ với một object khác của type_info hoặc cũng có thể dùng để lấy ra string có chứa tên của kiểu dữ liệu thông qua phương thức name() của type_info.
Example 1
1 2 3 4 5 6 7 8 9 10 11 |
#include <iostream> #include <typeinfo> int main() { int speed = 110; std::cout << typeid(speed).name() << '\n'; if (typeid(speed) == typeid(int)) { std::cout << "typeid(speed) == typeid(int)" << std::endl; } } |
1 2 |
i typeid(speed) == typeid(int) |
Example 2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#include <iostream> #include <typeinfo> using namespace std; int main () { int * a,b; a=0; b=0; if (typeid(a) != typeid(b)) { cout << "a and b are of different types:\n"; cout << "a is: " << typeid(a).name() << '\n'; cout << "b is: " << typeid(b).name() << '\n'; } return 0; } |
1 2 3 |
a and b are of different types: a is: Pi b is: i |
Example 3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
#include <iostream> #include <typeinfo> #include <exception> using namespace std; class CBase { virtual void f(){} }; class CDerived : public CBase {}; int main () { CBase* a = new CBase; CBase* b = new CDerived; cout << "a is: " << typeid(a).name() << '\n'; cout << "b is: " << typeid(b).name() << '\n'; cout << "*a is: " << typeid(*a).name() << '\n'; cout << "*b is: " << typeid(*b).name() << '\n'; return 0; } |
1 2 3 4 |
a is: P5CBase b is: P5CBase *a is: 5CBase *b is: 8CDerived |
Nhìn vào ouput của các ví dụ có thể thấy rằng hàm name() không đảm bảo trả về string chính xác tên của kiểu dữ liệu nên anh em chỉ nên sử dụng nó để log ra thông tin chứ đừng sử dụng nó để check kiểu dữ liệu. Để check kiểu thì hãy dùng các toán tử so sánh của type_info.
Ngoài ra có thể thấy rằng khi dùng typeid với tham số là một con trỏ như ‘b‘ thì thông tin mà typeid trả về là thông tin của bản thân con trỏ đó. Tuy nhiên, khi typeid dùng với object như ‘*b‘ thì thông tin kiểu dữ liệu mà typeid trả về là thông tin của cái gọi là ‘most derived class type‘. (anh em thông cảm dịch sang tiếng Việt khó vãi).
Để hiểu ‘most derived class type‘ là gì thì xem ví dụ sau →
1 2 3 4 5 6 |
class Base1 {}; class Derived1 : Base1 {}; class Base2 {}; class Foo: Derived1, Base2 {}; Foo obj; |
— Phạm Minh Tuấn (Shun) —