Wie kann man in Enitity beliebig viele equals Methoden schaffen, die allel false liefern, außer, wenn Entity e auch ein DimensionEntety ist.
class Entity
{
bool equals( Entity const & )
{
}
//virtual bool equals( Entity sub const & ) // <- das müsste das Ziel sein
// else return false;
//virtual bool equals( Entity sub const & ) : false; // <- das müsste das Ziel sein
template< typename T >
bool equals( T const & )
{
static_assert( T is base of Entity )
return false;
}
}
class SubEntity : public Entity
{
int b;
bool equals( thistype const & other )
{
return other.b == this.b
}
}
class DimensionEntity : public Enitity
{
int a;
bool equals( thistype const & e )
{
return other.a = this.a;
}
}
SubEntity sub;
DimensionEntity dim;
Entity ref esub = sub;
Entity ref dsub = dim;
dim.equals( sub ); // ruft DimensionEntity::Entity::equals( SubEntity ) -> false;
dim.equals( dim ); // ruft DimensionEntity::equals( DimensionEntity ) -> true;
sub.equals( dsub ); // ruft SubEntity::Entity::equals( Entity ); -> dsub.equals( SubEntity ); -> dsub wird aufgelöst hat ein thistype zu implementieren -> dsub->SubEntity::equals( thistype ) wird gerufen
esub.equals( dsub ); // ruft Entity::equals( DimensionEntity ) -> esub vergleicht Typ mit dsub, wenn gleich suche nach Funktion mit thistype )
Die Funktion equals(thistype) entspricht bei SubEntity der Signatur equals( Subentity & ), bei DimensionEntity der Funktion equals( DimensionEntity ). Hat Entity jetzt ein virtual equals( SubEntity ), so muss SubEntity zwei Funktionspointer zur gleichen Funktion zeigen lassen
Man kann sich die ganzen AsThisType sparen. Man ruft die Funktion und bekommt entweder ein definiertes Nopes zurück oder ein Ergebnis.
class Base
{
virtual thisType * As##CLASSNAME : nullptr;
virtual bool DoSomethingWith( thistype ) : false;
};
class Sub1 : Base
{
virtual thisType * As##CLASSNAME : this;
virtual bool DoSomethingWith( thistype ) : true;
}
class Sub2 : Base
{}
class Sub12 : Sub1
{
}
Sub1 s1;
Sub2 s2;
Sub12 s12;
s1.DoSomethingWith( s2 ); // es gibt keine Sub1::DoSomethingWith( Sub2 ), also wird Base::DoSomethingWith( Base ) gerufen->false;
s1.DoSomethingWith( s12 ); // Es gibt keine Sub1::DoSomethingWith( Sub12 ), aber Sub12 ist auch ein Sub1. Es wird Sub1::DoSomethingWith( Sub1 ) gerufen -> true