Hallo,
ich habe testweise mal einen ähnlichen Ableitungsbaum aufgebaut wie man ihn für dynamic_cast benötigt und die Zeit verglichen.
Jedenfalls braucht die dynamic_cast-Version bei mir (selbst bei -O3, gcc-3.3.3) 2.91 Sekunden gegenüber 0.19 für die selbstgeschriebene.
Auch wenn ich das nicht überall einsetzen sollte / will, wollte ich nur mal fragen, ob ich irgendetwas dabei übersehen habe?
Mehrfachvererbung funktioniert damit ja, ebenso wie Templates (wieso auch nicht) …
Könnte es sein, das bei private oder protected-Vererbung da was nicht klappe könnte?
thx TLF
(Kompilerschalter: 2 Versionen mit -DDYNAMIC)
#include
#include
#include
class CClassDesc {};
#define DECLARE_BEGIN \
public: \
static const CClassDesc __meta; \
virtual void* \
__subquery (const CClassDesc* x) \
{ \
if (x == &__meta) \
return this; \
void* result;
#define DECLARE_QUERY(base) \
result = base::__subquery (x); \
if (result) goto found;
#define DECLARE_END \
found: \
return result; \
}
class CAClass
{
public:
static const CClassDesc __meta;
virtual ~CAClass () {};
template X*
query ()
{
return (X*) __subquery (&X::__meta);
}
virtual void*
__subquery (const CClassDesc* x)
{
if (x == &__meta)
return this;
else
return 0;
}
};
class CBClass : public virtual CAClass
{
public:
static const CClassDesc __meta;
virtual ~CBClass () {};
virtual void*
__subquery (const CClassDesc* x)
{
if (x == &__meta)
return this;
else
return CAClass::__subquery (x);
}
};
class CCClass : public virtual CAClass
{
public:
static const CClassDesc __meta;
virtual ~CCClass () {};
virtual void*
__subquery (const CClassDesc* x)
{
if (x == &__meta)
return this;
else
return CAClass::__subquery (x);
}
};
class CDClass : public CBClass, public CCClass
{
public:
virtual ~CDClass () {};
/*virtual void*
subquery (const CClassDesc* x)
{
if (x == &meta)
return this;
void* result = CBClass::subquery (x);
if (result)
return result;
return CCClass::subquery (x);
}*/
DECLARE_BEGIN
DECLARE_QUERY (CBClass)
DECLARE_QUERY (CCClass)
DECLARE_END
};
template
class TEClass : public CDClass
{
public:
static const CClassDesc __meta;
virtual ~TEClass () {};
virtual void*
__subquery (const CClassDesc* x)
{
if (x == &__meta)
return this;
return CDClass::__subquery (x);
}
};
const CClassDesc CAClass::__meta = CClassDesc ();
const CClassDesc CBClass::__meta = CClassDesc ();
const CClassDesc CCClass::__meta = CClassDesc ();
const CClassDesc CDClass::__meta = CClassDesc ();
const CClassDesc TEClass ::__meta = CClassDesc ();
int
main ()
{
clock_t start, end;
clock_t cpu_cycles_used;
long double cpu_time_used;
int i;
CAClass* a = new CAClass ();
CAClass* b = new CBClass ();
CAClass* c = new CCClass ();
CAClass* d = new CDClass ();
CAClass* e = new TEClass ();
CAClass* result = 0;
start = clock ();
for (i = 0; i (e);
#else
result = e->query ();
#endif
end = clock ();
cpu_cycles_used = end - start;
cpu_time_used = ((long double) (end - start)) / CLOCKS_PER_SEC;
if (result)
printf („result is TRUE\n“);
else
printf („result is FALSE\n“);
printf ("%d %Lf\n", cpu_cycles_used, cpu_time_used);
printf ("%d %d %d %d %d\n",
sizeof (CAClass),
sizeof (CBClass),
sizeof (CCClass),
sizeof (CDClass),
sizeof (TEClass )
);
printf ("%d\n", sizeof (CClassDesc));
CAClass a2;
if (&a->__meta == &a2.__meta)
printf („a and a2 are of the same class\n“);
return 0;
}