Trang tài liệu
Khóa học C++ nền tảng
Chương 5. Kiểu dữ liệu
Nhận dạng loại thời gian chạy (RTTI)

Nhận dạng loại thời gian chạy (RTTI)

Nhận dạng loại thời gian chạy (RTTI) là một tính năng trong C++ cho phép bạn lấy thông tin loại của một đối tượng trong khi thực hiện chương trình. Điều này có thể hữu ích khi sử dụng kiểu nhập động, trong đó loại đối tượng có thể thay đổi khi chạy.

Có hai cơ chế chính cho RTTI trong C++:

  • toán tử typeid
  • toán tử dynamic_cast

Toán tử typeid

typeid là một toán tử trả về một tham chiếu đến một đối tượng có kiểu std::type_info, chứa thông tin về kiểu của đối tượng. Nên thêm tệp tiêu đề để sử dụng typeid.

Đây là một ví dụ:

#include <iostream>
#include <typeinfo>

class Base { virtual void dummy() {} };
class Derived : public Base { /* ... */ };

int main() {
    Base* base_ptr = new Derived;

    // Sử dụng typeid để lấy kiểu đối tượng
    std::cout << "Type: " << typeid(*base_ptr).name() << '\n';

    delete base_ptr;
    return 0;
}

Toán tử dynamic_cast

dynamic_cast là một toán tử ép kiểu thực hiện kiểm tra kiểu trong thời gian chạy và hạ thấp một cách an toàn một con trỏ cơ sở hoặc tham chiếu đến một con trỏ hoặc tham chiếu dẫn xuất. Nó trả về giá trị null hoặc đưa ra một ngoại lệ bad_cast (nếu truyền tham chiếu) khi quá trình truyền không thành công.

Đây là một ví dụ:

#include <iostream>

class Base { virtual void dummy() {} };
class Derived1 : public Base { /* ... */ };
class Derived2 : public Base { /* ... */ };

int main() {
    Base* base_ptr = new Derived1;

    // Sử dụng dynamic_cast để hạ thấp con trỏ một cách an toàn
    Derived1* derived1_ptr = dynamic_cast<Derived1*>(base_ptr);
    if (derived1_ptr) {
        std::cout << "Downcast to Derived1 successful\n";
    }
    else {
        std::cout << "Downcast to Derived1 failed\n";
    }

    Derived2* derived2_ptr = dynamic_cast<Derived2*>(base_ptr);
    if (derived2_ptr) {
        std::cout << "Downcast to Derived2 successful\n";
    }
    else {
        std::cout << "Downcast to Derived2 failed\n";
    }

    delete base_ptr;
    return 0;
}

Xin lưu ý rằng việc sử dụng RTTI có thể có một số chi phí hoạt động, vì nó yêu cầu lưu trữ và xử lý thông tin bổ sung do trình biên dịch tạo trong thời gian chạy.