1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
|
/* +------------------------------------------------------------------------+
| Mobile Robot Programming Toolkit (MRPT) |
| https://www.mrpt.org/ |
| |
| Copyright (c) 2005-2023, Individual contributors, see AUTHORS file |
| See: https://www.mrpt.org/Authors - All rights reserved. |
| Released under BSD License. See: https://www.mrpt.org/License |
+------------------------------------------------------------------------+ */
/** \example rtti_example1/test.cpp */
//! [example-define-class]
#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)
//! [example-define-class]
//! [example-define-class-test]
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();
}
}
//! [example-define-class-test]
//! [example-factory]
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();
}
}
}
//! [example-factory]
int main(int argc, char** argv)
{
try
{
Test_UserTypes();
Test_UserTypesFactory();
return 0;
}
catch (const std::exception& e)
{
std::cerr << "MRPT error: " << mrpt::exception_to_str(e) << std::endl;
return -1;
}
}
|