dynamic_cast

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;
}