operator überladen und templates



  • hallo zusammen,

    ich habe eine templateklasse reference, welche eine anzahl von operatoren überlädt.

    template <typename T>
            class Reference {
                template <typename S>
                friend std::ostream & operator<<(std::ostream & stream, const Reference<S> & ref);
            public:
                Reference();
                Reference(const T & value);
                Reference(const Reference<T> & orig);
                virtual ~Reference();
                Reference<T> & operator=(const Reference<T> & rhs);
                Reference<T> operator+(const unsigned int & rhs);
                Reference<T> operator+(const Reference<T> & rhs);
                Reference<T> operator-(const Reference<T> & rhs);
                Reference<T> operator*(const unsigned int & rhs);
                bool operator==(const Reference<T> & rhs) const;
                bool operator!=(const Reference<T> & rhs) const;
                bool operator<(const Reference<T> & rhs) const;
                bool operator>(const Reference<T> & rhs) const;
                //++a
                Reference<T> & operator++();
                //a++
                Reference<T> operator++(int);
                void set(Archive &archive);
                virtual T getValue() const;
            protected:
                T value;
            };
    

    Eine Reference als solches ist sowas wie eine PeerID, eine Transaktionsnummer oder eine MessageReference. Dann habe ich eine Klasse MessageReference, welche eine Reference ist.

    class MessageReference : public Reference<unsigned int>  {
                friend std::ostream & operator<<(std::ostream & stream, const MessageReference & mRef);
            public:
                MessageReference();
                MessageReference(MessageReference const & orig);
                MessageReference(PeerID peerID, unsigned int sequ);
                virtual ~MessageReference();
                PeerID getPeerID();
                void setPeerID(PeerID peerID);
                int getSequenceNumber();
                void setSequenceNumber(int sequ);
                MessageReference & operator=(const MessageReference & rhs);
                bool operator==(const MessageReference & o);
                //++a
                MessageReference& operator++();
                //a++
                void operator++(int);
            private:
                static const unsigned int MessageReferencePeerIDOffset = 100000;
            };
    

    In der Überladung des operators++ mach ich folgendes:

    MessageReference&
            MessageReference::operator++(){
    
                value= MessageReferencePeerIDOffset * getPeerID() + getSequenceNumber() + 1;
                return *this;
    
            }
    

    Dies führt zu folgenden Fehler:

    common/transport/MessageReference.cc: In member function 
    'MessageReference& MessageReference::operator++()’:
    common/transport/MessageReference.cc:111: error: no match for ‘operator*’ in ‘MessageReference::MessageReferencePeerIDOffset * MessageReference::getPeerID()()’
    libs/inet/src/util/uint128.h:286: note: candidates are: Uint128 operator*(const Uint128&, const Uint128&)
    /opt/omnetpp-4.2.2/include/simtime.h:269: note:                 const SimTime operator*(double, const SimTime&)
    /opt/omnetpp-4.2.2/include/simtime.h:264: note:                 const SimTime operator*(const SimTime&, double)
    

    Ändere ich die Methode in:

    value= MessageReferencePeerIDOffset * getPeerID().getValue() + getSequenceNumber() + 1;
    

    geht es. Kann mir jemand verraten, wie ich die Operatoren korrekt definiere/deklariere damit diese Variante überflüssig ist?

    Schon mal dank.

    sven_


  • Mod

    Wie wäre es wenn du uns
    1. Den echten Code zeigst, denn MessageReference::getPeerID()() sehe ich nirgends in deinen Code-Schnipseln,
    2. Die Definition der entscheidenden Klasse PeerID zeigst.

    Wahrscheinlich willst du einen Konvertierungsoperator. Oder vielleicht auch nicht.



  • ausserdem: was bringt ein postinkrementoperator der nichts zurückgibt? da kann man ja gleich den präinkrementoperator aufrufen.



  • Hallo Arcoth,

    vielen Dank für deine Antwort. PeerID ist nix weiter, außer:

    class PeerID : public Reference<unsigned int> {
            public:
    
                PeerID() : Reference<unsigned int>(0) {
                }
    
                PeerID(unsigned int data) : Reference<unsigned int>(data) {
                }
            };
    
            static const PeerID UNDEFINED_PEER_ID = 0;
            static const PeerID INITIAL_PEER_ID = 1;
    

    Es ist der echte Code. Oder willst du die Deklaration von MessageReference::getPeerID() ? Diese wäre:

    PeerID
            MessageReference::getPeerID() {
                return value / MessageReferencePeerIDOffset;
            }
    

    Gruß
    sven_



  • Ah, da ist also ein Fehler,

    so habe ich erstmal die a++ definition geändert in:

    MessageReference
            MessageReference::operator++(int){
    
                MessageReference result(*this);
                result.value = MessageReferencePeerIDOffset * getPeerID().getValue() + getSequenceNumber() + 1;
                return result;            
    
            }
    


  • sven_ schrieb:

    Ah, da ist also ein Fehler,

    so habe ich erstmal die a++ definition geändert in:

    MessageReference
            MessageReference::operator++(int){
    
                MessageReference result(*this);
                result.value = MessageReferencePeerIDOffset * getPeerID().getValue() + getSequenceNumber() + 1;
                return result;            
    
            }
    

    kleiner tipp: um rendundanz zu vermeiden greift man mit dem postinkrementoperator auf den präinkrementoperator zu. hat z.b. den vorteil, dass man allfällige fehler nur in einer version ausbessern muss:

    MessageReference
            MessageReference::operator++(int){
    
                MessageReference result(*this);
                ++(*this); // Hier
                return result;            
    
            }
    


  • Hallo nochmal,

    angenommen es gibt eine Klasse A, welche ein Member PeerID hat. Was ich nicht verstehe ist, dass wenn ich sowas mache:

    PeerID 
    A::createPeerID(){
    return aPeerIO++;
    }
    

    Ich folgenden Fehler erhalte:

    error: conversion from ‘Reference<unsigned int>’ to non-scalar type ‘ubeeme::moversight::PeerID’ requested
    

    Was ist da falsch, an meiner Reference Klasse??

    Danke nochmal.


Log in to reply