kopierklasse



  • ist folgendes möglich

    template <class t_this, class t_source>
    class ccopy
    {
    	public:
    		ccopy() {};
    		ccopy(const t_source& src) {copy(src)};
    		virtual t_this& copy(const t_source& src) = 0;
    		t_this& operator = (const t_source& src) {return copy(src)};
    };
    

    um diese klasse als basis für andere klassen zu nehmen, damit ich da nur noch die copy()-funktion definieren muss und der "copy"-construkor und =operator schon definiet sind?

    Bsp.:

    template <class t>
    class myclass : virtual public ccopy<myclass<t>, myclass<t>>, virtual public ccopy<myclass<t>, t>
    {
    	private:
    		t data;
    	public:
    		myclass<t>& copy(const myclass<t>& src) {data = src.data};
    		myclass<t>& copy(const t& src) {data = src};
    };
    
    int main()
    {
    //sollte jetzt alles durch die basis-klasse ccopy definiert sein
    	myclass<int> a(2);
    	myclass<int> b(a);
    	myclass<int> c(0);
    	c = b;
    	return 0;
    };
    

  • Mod

    void main()
    

    bitte nicht

    myclass<int> a(2);
    

    Frag deinen Compiler.

    ccopy(const t_source& src) {copy(src)};
            virtual t_this& copy(const t_source& src) = 0;
    

    So geht es nicht. Innerhalb es Funktionsrumpfes eines Konstruktors existiert nur die Klasse selbst schon (jedenfalls alle member und Basisklassenobjekte, bestimmte Invarianten sind möglicherweise noch nicht gegeben) - nicht aber der Teil, der zur abgeleiteten Klasse gehört. Mithin sind hier statischer und dynamischer Typ identisch und ein dynamischer Aufruf einer virtuellen Funktion findet dann konsequenterweise die Implementation in der Klasse, dessen Konstruktor aufgerufen wird. Jedenfalls wäre es so, wenn copy nicht rein virtuell wäre - in diesem Falle ist das Verhalten schlicht undefiniert, sogar dann, wenn du copy eine Implementation spendierst.
    Mir ist allerdings auch nicht ganz klar, was du überhaupt bezwecken willst - ob und wann du einer Klasse eine eigene Kopiersemantik spendieren musst, ist schließlich nicht Teil eines Interfaces.



  • ccopy(const t_source& src) {copy(src);};
    

    Thus spoke the Giver Of Data:
    "Thou shall not call virtual functions within a counstructor and what thou shall not call therein are virtual functions!"

    - Bei MSVC 5 gab's einen Compiler-Switch für ein sog. "Construction-Displacement" mit dem sowas ging
    => Furchtbarer Schmutzschalter!

    - Manche g++-Versionen kompilieren sowas und dann wirft's "pure virtual funktion call" => stylische Art aus Programmen "auszusteigen" 🙂

    - VC Express 05 linked es (zumindest by default) gar nicht erst (ich hoffe inständig dass man dies nicht irgendwie wieder einschalten kann)

    Grüsse

    *this



  • vor allem ist es sehr verschwenderisch virtuelle-Vererbung und Methoden für seine eigene Faulheit zu benutzen.



  • also wenn ich den kopierkonstruktor weglasse, dann funktioniert es?
    also wenn ich quasi nur noch den zuweisungsoperator drin habe und die copy-methode abstrakt ist?

    @rüdiger: warum verschwendung? so minimiere ich doch fehlerquellen. weil ich hab das zum beispiel auch mit operatoren +=, -=, *=, /=, -, +, *, / vor, dass ich also nur +=, -=, *=, /= definiere und -, +, *, / daraus resultieren.



  • Wenn du boost benutzten würdest müsstest du das Rad nicht neu erfinden 💡



  • was ist denn boost?



  • FreakyBKA schrieb:

    was ist denn boost?

    Google: boost ➡ http://www.boost.org/libs/utility/operators.htm



  • und die machen das alles ohne virtuelle-Vererbung. -,+ etc. sollten ja ohnehin nicht als Memberfunktionen implementiert werden!



  • dein Ansatz ist falsch, C++ ist nicht java, in C++ erstellt man keine klasse copyable oder so, man schreibt einfach den Copykonstruktor neu, falls der standart copykonstruktor nicht zurifft (alle variablen kopieren)



  • Krux schrieb:

    dein Ansatz ist falsch, C++ ist nicht java, in C++ erstellt man keine klasse copyable oder so

    Ich wüsste nicht, was dagegen spricht. Boost macht es ja auch so. Das Vorgehen ist gut; zumal der kommende C++-Standard dafür sogar mit den Concepts eine explizite Syntax-Unterstützung für bietet.


Anmelden zum Antworten