erben von template klasse



  • Hallo leute,

    ich hatte gestern die abstruse idee in C++ eine Klasse zu
    schreiben 😮 die ein ähnliches verhalten aufweist wie
    die aus den Microsoft "Managed Code"-Sprachen bekannten
    "Properties"!Also setzte ich mich ran und baute einen kleinen, süßen Container:

    #ifndef PROPERTY_HPP
    #define PROPERTY_HPP
    
    template<class T>
    class property
    {
        protected:
            T _instance;
    
        protected:
            virtual T get() { return this->_instance; }
            virtual void set(T& type) { this->_instance = type;}
    
        public:
            T operator =(T& type) { this->set(type); }
            operator T() { return this->get(); }
    };
    
    #endif
    

    Mein Plan war, das man die get/set Funktionen in geerbten Klassen
    überschreiben kann und dort evtl. eigenen Code einfügt,
    der dann mittels der operatoren ausgeführt wird!

    Dieses habe ich dann auch gleich probiert:

    class intprop : public property<int>
    {
        private:
            void set(int &type)
            {
                this->_instance;
                type++;
            }
    };
    
    class proptest
    {
        public:
            intprop intProp;
    };
    

    so weit, so gut!aber:

    int main(void)
    {
        proptest oproptest;
        int test = 22;
    
        [b]oproptest.intProp = test;[/b]
        std::cout << oproptest.intProp  << std::endl;
    
        std::cin.get();
        return EXIT_SUCCESS;
    }
    

    an der makierten Stelle gibt er mir folgenden Fehler:

    no match for 'operator=' in 'oproptest.proptest::intProp = test'
    candidates are: myint& myint::operator=(const myint&)
    

    jetzt frage ich mich doch: warum?!so wie ich mir das gedacht
    hatte müsste er doch beim erben die "int" als Template-Typ für
    die Funktionen usw. übernehmen oder nich?



  • Du erbst aber meines Wissens nicht den operator=
    Den muesstest du fuer intprop nochmal definieren:

    int intprop::operator=(int type) { return property<int>::operator=(type); }
    

    Du koenntest auch direkt set aufrufen, aber durch benutzung des operators der elternklasse stellst du sicher, dass das Verhalten konsistent bleibt, wenn du den in der elternklasse aenderst (z.B. irgendwelche aktionen vorm set ausfuehrst)



  • pumuckl schrieb:

    Du erbst aber meines Wissens nicht den operator=
    Den muesstest du fuer intprop nochmal definieren:

    int intprop::operator=(int type) { return property<int>::operator=(type); }
    

    aber das ist doch das Problem!ich erbe die operatoren ja,nur mit dem falschen
    typ!normaler weise wollte ich ja int als typ haben aber er hat
    mir einfach myint draus gemacht.verrückte welt.das wiederspricht meiner
    logik schon ein bischen. 😕

    pumuckl schrieb:

    Du koenntest auch direkt set aufrufen, aber durch benutzung des operators der elternklasse stellst du sicher, dass das Verhalten konsistent bleibt, wenn du den in der elternklasse aenderst (z.B. irgendwelche aktionen vorm set ausfuehrst)

    und nicht nur das:ich wollte mit den operatoren das Verhalten von "Properties"
    nachahmen



  • Operatoren lassen sich nicht vererben. Muß man immer wieder neu implementieren.


  • Mod

    Operatoren werden wie normale Funktionen vererbt, auch unser operator= aus property<int>. Allerdings wird dieser geerbte Operator durch den implizit deklarierten Copy-Zuweisungsoperator in intprop verdeckt.



  • Hi,

    mit

    class intprop : public property<int>
    {
    public:
       using property<int>::operator=;
    ...
    

    geht's jedenfalls.

    Gruß,

    Simon2.



  • vielen dank für die ganzen antworten.gib es nicht vielleicht
    irgendein schönen flag das den operator erzwingt?!



  • Der Compiler generiert für jede Klasse, die keinen hat, einen operator=. Dieser verdeckt den geerbten. Was soll da erzwungen werden? Die Regeln der Sprache zu ignorieren?



  • aber es wiederspricht doch auch der Sprache wenn er alle
    public funktionen public setzt nur die operatoren nich...also
    die 3 standard-dinger auf jedenfall..



  • Basingstoke schrieb:

    aber es wiederspricht doch auch der Sprache wenn er alle
    public funktionen public setzt nur die operatoren nich...also
    die 3 standard-dinger auf jedenfall..

    Also den Satz verstehe ich nicht. Möchtest Du ihn vielleicht nochmal neu formulieren?

    Jedenfalls widerspricht diese Regel nicht der allgemeinen Regel zum Verdecken von Funktionen in Ableitungen, wie dieses Beispiel zeigt.

    class Base
    {
        public:
            void doIt(int);
    };
    
    class Derived: Base
    {
        public:
            void doIt(char const*);
    };
    
    int main()
    {
        Derived d;
        d.doIt(12); // error: invalid conversion from `int' to `const char*'
    }
    

    Nichts anderes passiert bei Dir. Der vom Compiler generierte operator=(intprop const&) verdeckt den geerbten operator=(int), genauso wie doIt(char const*) doIt(int) verdeckt (das bedeutet nicht, dass doIt(int) plötzlich nicht mehr public ist). Mit using Base::doIt in der Derived-Klasse funktioniert der Code jedoch.


Anmelden zum Antworten