====== virtual thistype ====== 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 ===== Was bringt das ===== 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