C2446 bei self assignment check



  • Guten Abend,

    ich habe ein Problem beim Self-Assignment-Check, welches mir nicht so richtig klar wird. Ich erhalte einen C2446 Error: Keine Konvertierung von 'const MyClass<int,false> *' in 'MyClass<int,true> *const '. Dabei prüfe ich aber nur die Adressen!?
    Die ausgeklammerte Variante macht doch im Prinzip auch nichts anderes, funktioniert aber.

    Auch das Überladen des == Operators bringt nichts.

    Könnte mir vielleicht einer von euch sagen, was da schief läuft?

    template <typename T, bool Condition>
    class MyClass
    {
        public:
    
            template <bool TheObjectCondition>
            MyClass &operator = (const MyClass <T, TheObjectCondition> &TheObject)
            {
                if (this == &TheObject)
                    return *this;
    
                return *this;
            }
    
            /*
            template <bool TheObjectCondition>
            MyClass &operator = (const MyClass <T, TheObjectCondition> &TheObject)
            {
                const void *ThisPtr = this;
                const void *ObjPtr = &TheObject;
    
                if (ThisPtr == ObjPtr)
                    return *this;
    
                return *this;
            }
            */
    };
    
    int main ()
    {
        MyClass <int, true> Object1;
        MyClass <int, false> Object2;
        Object1 = Object2;
    
        return 0;
    }
    

  • Mod

    Das eine ist eben ein Pointer auf MyClass<int, true>, das andere ein Pointer auf MyClass<int, false>. Das sind zwei ganz verschiedene Klassen, bloß ihr Name ist ähnlich. Wenn du

    class MeineKlasse1;
    class MeineKlasse2;
    

    hättest, würdest du dich wohl auch nicht wundern, wenn ein Vergleich von Zeigern auf diese Klasse nicht funktioniert, oder? Ebensowenig macht wohl eine Zuweisung von Objekten der einen Klasse zu Objekten der anderen Klasse Sinn: Es sind zwei gänzlich verschiedene Klassen, selbst wenn sie nach der gleichen Vorlage (Template) erzeugt wurden.

    Allgemein bezüglich Selbstzuweisung zitiere ich hier mal Exceptional C++:

    Herb Sutter schrieb:

    Exception-unsafe" and "poor design" go hand in hand. If a piece of code isn't exception-safe, that's generally okay and can simply be fixed. But if a piece of code cannot be made exception-safe because of its underlying design, that almost always is a signal of its poor design.

    Example 1: A function with two different responsibilities is difficult to make exception-safe.

    Example 2: A copy assignment operator that is written in such a way that it must check for self-assignment is probably not strongly exception-safe either

    Hervorhebung durch mich.

    Besserer Zuweisungsoperator:

    Klasse &operator=(Klasse k)
    {
      k.swap(*this);   // Vertausche alle Ressourcen von k und *this
      return *this; 
    }
    

    Kurz und knackig, exceptionsicher, keine Prüfung auf Selbstzuweisung nötig. Nennt sich Copy&Swap Idiom. Der Kopierkonstruktor und Destruktor erledigen die ganze schwere Arbeit bezüglich des Ressourcenhandlings, der Zuweisungsoperator erledigt nur das simple Vertauschen der Ressourcen.



  • Danke dir.


Anmelden zum Antworten