[mrpt-rtti]
Runtime Type Information (RTTI) library, providing compiler-independent class registry, class factory, and inheritance information.
Library mrpt-rtti
This library is part of MRPT and can be installed in Debian-based systems with:
sudo apt install libmrpt-rtti-dev
Read also how to import MRPT into your CMake scripts.
Any class with RTTI support has to be derived from mrpt::rtti::CObject, either directly or via a hierarchy of inheriting classes. Class factory by name enables deserialization of polymorphic classes in the library [mrpt-serialization].
All classes defined in each MRPT module are automatically registered when loading the module (if dynamically linked).
Example #1: defining new user classes
See: rtti_example1/test.cpp
#include <mrpt/rtti/CObject.h> #include <iostream> #include <memory> namespace MyNS { class Foo : public mrpt::rtti::CObject { public: Foo() {} DEFINE_MRPT_OBJECT(Foo, MyNS) void printName() { std::cout << "printName: Foo" << std::endl; } }; class BarBase : public mrpt::rtti::CObject { public: BarBase() {} DEFINE_VIRTUAL_MRPT_OBJECT(BarBase) virtual void printName() { std::cout << "printName: BarBase" << std::endl; } }; class Bar : public BarBase { public: Bar() {} DEFINE_MRPT_OBJECT(Bar, MyNS) void printName() override { std::cout << "class: Bar" << std::endl; } void specificBarMethod() { std::cout << "specificBarMethod: reached." << std::endl; } }; } // namespace MyNS IMPLEMENTS_MRPT_OBJECT(Foo, mrpt::rtti::CObject, MyNS) IMPLEMENTS_VIRTUAL_MRPT_OBJECT(BarBase, mrpt::rtti::CObject, MyNS) IMPLEMENTS_MRPT_OBJECT(Bar, MyNS::BarBase, MyNS)
void Test_UserTypes() { using namespace MyNS; const auto id_foo = CLASS_ID(Foo); std::cout << "RTTI Foo (static): " << id_foo->className << std::endl; // Pointers: Bar::Ptr pBar = std::make_shared<Bar>(); BarBase::Ptr pBase = mrpt::ptr_cast<BarBase>::from(pBar); mrpt::rtti::CObject::Ptr pObj = mrpt::ptr_cast<mrpt::rtti::CObject>::from(pBar); pBar->printName(); pBase->printName(); std::cout << "Is Foo? => " << (IS_DERIVED(*pObj, Foo) ? "Yes\n" : "No\n"); std::cout << "Is BarBase? => " << (IS_DERIVED(*pObj, BarBase) ? "Yes\n" : "No\n"); std::cout << "Is Bar? => " << (IS_DERIVED(*pObj, Bar) ? "Yes\n" : "No\n"); if (IS_CLASS(*pObj, Bar)) { auto pBar2 = mrpt::ptr_cast<Bar>::from(pObj); pBar2->specificBarMethod(); } }
Output:
RTTI Foo (static): Foo class: Bar class: Bar Is Foo? => No Is BarBase? => Yes Is Bar? => Yes specificBarMethod: reached.
Example #2: using the class factory
See: rtti_example1/test.cpp
#include <mrpt/rtti/CObject.h> #include <iostream> #include <memory> namespace MyNS { class Foo : public mrpt::rtti::CObject { public: Foo() {} DEFINE_MRPT_OBJECT(Foo, MyNS) void printName() { std::cout << "printName: Foo" << std::endl; } }; class BarBase : public mrpt::rtti::CObject { public: BarBase() {} DEFINE_VIRTUAL_MRPT_OBJECT(BarBase) virtual void printName() { std::cout << "printName: BarBase" << std::endl; } }; class Bar : public BarBase { public: Bar() {} DEFINE_MRPT_OBJECT(Bar, MyNS) void printName() override { std::cout << "class: Bar" << std::endl; } void specificBarMethod() { std::cout << "specificBarMethod: reached." << std::endl; } }; } // namespace MyNS IMPLEMENTS_MRPT_OBJECT(Foo, mrpt::rtti::CObject, MyNS) IMPLEMENTS_VIRTUAL_MRPT_OBJECT(BarBase, mrpt::rtti::CObject, MyNS) IMPLEMENTS_MRPT_OBJECT(Bar, MyNS::BarBase, MyNS)
void do_register() { // Register with explicit namespace: mrpt::rtti::registerClass(CLASS_ID_NAMESPACE(Foo, MyNS)); { // Register without explicit namespace: using namespace MyNS; mrpt::rtti::registerClass(CLASS_ID(BarBase)); mrpt::rtti::registerClass(CLASS_ID(Bar)); mrpt::rtti::registerClassCustomName("MyNS::Bar", CLASS_ID(Bar)); } } void Test_UserTypesFactory() { do_register(); // Test register: { const auto& allClasses = mrpt::rtti::getAllRegisteredClasses(); for (const auto& cl : allClasses) { std::cout << "Known class: " << cl->className << ", children of " << (cl->getBaseClass ? cl->getBaseClass()->className : "(none)") << std::endl; } } // Test factory: { mrpt::rtti::CObject::Ptr pObj = mrpt::rtti::classFactory("MyNS::Bar"); if (IS_CLASS(*pObj, MyNS::Bar)) { auto pBar = mrpt::ptr_cast<MyNS::Bar>::from(pObj); pBar->specificBarMethod(); } } }
Output:
Known class: Bar, children of BarBase Known class: BarBase, children of CObject Known class: CObject, children of (none) Known class: Foo, children of CObject Known class: Bar, children of BarBase specificBarMethod: reached.
Library contents
// structs struct mrpt::rtti::TRuntimeClassId; template <typename CAST_TO> struct mrpt::ptr_cast; // classes class mrpt::rtti::CListOfClasses; class mrpt::rtti::CObject; // global functions void mrpt::rtti::registerAllClasses_mrpt_rtti();
Global Functions
void mrpt::rtti::registerAllClasses_mrpt_rtti()
Forces manual RTTI registration of all serializable classes in this namespace.
Should never be required to be explicitly called by users, except if building MRPT as a static library.