To check whether an instance belongs to or is derived from a specified class, use the following methods of the OdRxObject class:
These methods require a raw pointer to the class describing instance as an argument.
For example, consider the following hierarchy of classes: the AObj class is directly derived from the OdRxObject class; the BObj class and DObj class are derived from the AObj class; the CObj class is derived from the BObj class; the EObj class and FObj class are derived from the DObj class; the BObj, CObj classes are one branch of the tree; the DObj, EObj, FObj classes are other branch of the tree.
To declare the standard RTTI methods, use the ODRX_DECLARE_MEMBERS macro. The listed classes have the following definition:
class AObj : public OdRxObjectImpl<OdRxObject>
{
public:
ODRX_DECLARE_MEMBERS(AObj);
public:
AObj();
~AObj();
};
typedef OdSmartPtr<AObj> AObjPtr;
class BObj : public AObj
{
public:
ODRX_DECLARE_MEMBERS(BObj);
public:
BObj();
~BObj();
};
typedef OdSmartPtr<BObj> BObjPtr;
class CObj : public BObj
{
public:
ODRX_DECLARE_MEMBERS(CObj);
public:
CObj();
~CObj();
};
typedef OdSmartPtr<CObj> CObjPtr;
class DObj : public AObj
{
public:
ODRX_DECLARE_MEMBERS(DObj);
public:
DObj();
~DObj();
};
typedef OdSmartPtr<DObj> DObjPtr;
class EObj : public DObj
{
public:
ODRX_DECLARE_MEMBERS(EObj);
public:
EObj();
~EObj();
};
typedef OdSmartPtr<EObj> EObjPtr;
class FObj : public DObj
{
public:
ODRX_DECLARE_MEMBERS(FObj);
public:
FObj();
~FObj();
};
typedef OdSmartPtr<FObj> FObjPtr;
To implement the standard RTTI methods, use the ODRX_CONS_DEFINE_MEMBERS macro. When you specify the class names in this macro, you must keep the hierarchical order of inheritance. Methods of these classes have the following implementation:
ODRX_CONS_DEFINE_MEMBERS(AObj, OdRxObject, NEWOBJ_CONSTR);
AObj::AObj() {}
AObj::~AObj() {}
ODRX_CONS_DEFINE_MEMBERS(BObj, AObj, NEWOBJ_CONSTR);
BObj::BObj() {}
BObj::~BObj() {}
ODRX_CONS_DEFINE_MEMBERS(CObj, BObj, NEWOBJ_CONSTR);
CObj::CObj() {}
CObj::~CObj() {}
ODRX_CONS_DEFINE_MEMBERS(DObj, AObj, NEWOBJ_CONSTR);
DObj::DObj() {}
DObj::~DObj() {}
ODRX_CONS_DEFINE_MEMBERS(EObj, DObj, NEWOBJ_CONSTR);
EObj::EObj() {}
EObj::~EObj() {}
ODRX_CONS_DEFINE_MEMBERS(FObj, DObj, NEWOBJ_CONSTR);
FObj::FObj() {}
FObj::~FObj() {}
For testing these classes, the example creates an array of instances that will belong to other classes. To print information about the class hierarchy for each pair of instances of this array, the example implements the TestKindOf() function that uses the isKindOf() method, the TestQueryX() function that uses the queryX() method, and the TestX() function that uses the x() method. The PrintClassNames() function prints the class names and addresses of instances in the array. The Main module has the following implementation:
#include "OdaCommon.h"
#include "OdToolKit.h"
#include "..\..\Teigha.dwg\Extensions\ExServices\ExHostAppServices.h"
#include "..\..\Teigha.dwg\Extensions\ExServices\ExSystemServices.h"
class MyApp : public ExSystemServices
{
protected:
ODRX_USING_HEAP_OPERATORS(ExSystemServices);
public:
MyApp() {};
};
void PrintClassNames(OdRxObjectPtr pArr[], int count)
{
for(int i=0 ; i < count ; i++)
odPrintConsoleString(L"\nclass %s \tInstance %x", pArr[i]->isA()->name().c_str(), pArr[i]);
}
void TestKindOf(OdRxObjectPtr pArr[], int count)
{
for(int i=1 ; i < count ; i++)
for(int j=0 ; j < count ; j++)
if(i != j)
odPrintConsoleString(L"\nIs (%s) KindOf (%s) => %s", pArr[i]->isA()->name().c_str(),
pArr[j]->isA()->name().c_str(), (pArr[i]->isKindOf(pArr[j]->isA())) ? L"true" : L"false");
}
void TestQueryX(OdRxObjectPtr pArr[], int count)
{
for(int i=1 ; i < count ; i++)
for(int j=0 ; j < count ; j++)
if(i != j)
odPrintConsoleString(L"\nQuery (%s) --> (%s) => %x", pArr[i]->isA()->name().c_str(),
pArr[j]->isA()->name().c_str(), pArr[i]->queryX(pArr[j]->isA()));
}
void TestX(OdRxObjectPtr pArr[], int count)
{
for(int i=1 ; i < count ; i++)
for(int j=0 ; j < count ; j++)
if(i != j)
try
{
odPrintConsoleString(L"\nQuery (%s) --> (%s) => ", pArr[i]->isA()->name().c_str(), pArr[j]->isA()->name().c_str());
odPrintConsoleString(L"%x", pArr[i]->x(pArr[j]->isA()));
}
catch(OdError_NotThatKindOfClass err)
{
odPrintConsoleString(L"\nExcept %d - %s (KindOf)", err.code(), err.description().c_str());
}
try
{
odPrintConsoleString(L"\n%x", pArr[0]->x(NULL));
}
catch(OdError e)
{
odPrintConsoleString(L"\nExcept %d - %s ", e.code(), e.description().c_str());
}
}
#include <conio.h>
int main()
{
OdStaticRxObject<MyApp> svcs;
odInitialize(&svcs);
AObj::rxInit();
BObj::rxInit();
CObj::rxInit();
DObj::rxInit();
EObj::rxInit();
FObj::rxInit();
OdRxObjectPtr pArr[6];
pArr[0] = AObj::createObject();
pArr[1] = BObj::createObject();
pArr[2] = CObj::createObject();
pArr[3] = DObj::createObject();
pArr[4] = EObj::createObject();
pArr[5] = FObj::createObject();
PrintClassNames(pArr, 6);
getch();
TestKindOf(pArr, 6);
getch();
TestQueryX(pArr, 6);
getch();
TestX(pArr, 6);
getch();
FObj::rxUninit();
EObj::rxUninit();
DObj::rxUninit();
CObj::rxUninit();
BObj::rxUninit();
AObj::rxUninit();
odUninitialize();
return 0;
}
The PrintClassNames() function prints the following result:
class AObj Instance 135a510
class BObj Instance 135a528
class CObj Instance 135a540
class DObj Instance 135a558
class EObj Instance 135a570
class FObj Instance 135a588
The TestKindOf() function prints the following result:
Is (BObj) KindOf (AObj) => true
Is (BObj) KindOf (CObj) => false
Is (BObj) KindOf (DObj) => false
Is (BObj) KindOf (EObj) => false
Is (BObj) KindOf (FObj) => false
Is (CObj) KindOf (AObj) => true
Is (CObj) KindOf (BObj) => true
Is (CObj) KindOf (DObj) => false
Is (CObj) KindOf (EObj) => false
Is (CObj) KindOf (FObj) => false
Is (DObj) KindOf (AObj) => true
Is (DObj) KindOf (BObj) => false
Is (DObj) KindOf (CObj) => false
Is (DObj) KindOf (EObj) => false
Is (DObj) KindOf (FObj) => false
Is (EObj) KindOf (AObj) => true
Is (EObj) KindOf (BObj) => false
Is (EObj) KindOf (CObj) => false
Is (EObj) KindOf (DObj) => true
Is (EObj) KindOf (FObj) => false
Is (FObj) KindOf (AObj) => true
Is (FObj) KindOf (BObj) => false
Is (FObj) KindOf (CObj) => false
Is (FObj) KindOf (DObj) => true
Is (FObj) KindOf (EObj) => false
The TestQueryX() function prints the following result:
Query (BObj) --> (AObj) => 135a528
Query (BObj) --> (CObj) => 0
Query (BObj) --> (DObj) => 0
Query (BObj) --> (EObj) => 0
Query (BObj) --> (FObj) => 0
Query (CObj) --> (AObj) => 135a540
Query (CObj) --> (BObj) => 135a540
Query (CObj) --> (DObj) => 0
Query (CObj) --> (EObj) => 0
Query (CObj) --> (FObj) => 0
Query (DObj) --> (AObj) => 135a558
Query (DObj) --> (BObj) => 0
Query (DObj) --> (CObj) => 0
Query (DObj) --> (EObj) => 0
Query (DObj) --> (FObj) => 0
Query (EObj) --> (AObj) => 135a570
Query (EObj) --> (BObj) => 0
Query (EObj) --> (CObj) => 0
Query (EObj) --> (DObj) => 135a570
Query (EObj) --> (FObj) => 0
Query (FObj) --> (AObj) => 135a588
Query (FObj) --> (BObj) => 0
Query (FObj) --> (CObj) => 0
Query (FObj) --> (DObj) => 135a588
Query (FObj) --> (EObj) => 0
The TestX() function prints the following result:
Except 63 - Object of class BObj can't be cast to CObj. (KindOf)
Query (BObj) --> (DObj) =>
Except 63 - Object of class BObj can't be cast to DObj. (KindOf)
Query (BObj) --> (EObj) =>
Except 63 - Object of class BObj can't be cast to EObj. (KindOf)
Query (BObj) --> (FObj) =>
Except 63 - Object of class BObj can't be cast to FObj. (KindOf)
Query (CObj) --> (AObj) => 135a540
Query (CObj) --> (BObj) => 135a540
Query (CObj) --> (DObj) =>
Except 63 - Object of class CObj can't be cast to DObj. (KindOf)
Query (CObj) --> (EObj) =>
Except 63 - Object of class CObj can't be cast to EObj. (KindOf)
Query (CObj) --> (FObj) =>
Except 63 - Object of class CObj can't be cast to FObj. (KindOf)
Query (DObj) --> (AObj) => 135a558
Query (DObj) --> (BObj) =>
Except 63 - Object of class DObj can't be cast to BObj. (KindOf)
Query (DObj) --> (CObj) =>
Except 63 - Object of class DObj can't be cast to CObj. (KindOf)
Query (DObj) --> (EObj) =>
Except 63 - Object of class DObj can't be cast to EObj. (KindOf)
Query (DObj) --> (FObj) =>
Except 63 - Object of class DObj can't be cast to FObj. (KindOf)
Query (EObj) --> (AObj) => 135a570
Query (EObj) --> (BObj) =>
Except 63 - Object of class EObj can't be cast to BObj. (KindOf)
Query (EObj) --> (CObj) =>
Except 63 - Object of class EObj can't be cast to CObj. (KindOf)
Query (EObj) --> (DObj) => 135a570
Query (EObj) --> (FObj) =>
Except 63 - Object of class EObj can't be cast to FObj. (KindOf)
Query (FObj) --> (AObj) => 135a588
Query (FObj) --> (BObj) =>
Except 63 - Object of class FObj can't be cast to BObj. (KindOf)
Query (FObj) --> (CObj) =>
Except 63 - Object of class FObj can't be cast to CObj. (KindOf)
Query (FObj) --> (DObj) => 135a588
Query (FObj) --> (EObj) =>
Except 63 - Object of class FObj can't be cast to EObj. (KindOf)
Except 5 - Invalid input
Implementing RTTI Methods for the Derived Class
Belonging to an Instance of a Class
Copyright © 2002 – 2020. Open Design Alliance. All rights reserved.
|