web-dev-qa-db-fra.com

Comment surcharger l'opérateur ++ de deux manières différentes pour postfix a ++ et prefix ++ a?

Comment surcharger l'opérateur ++ de deux manières différentes pour postfix a++ et le préfixe ++a?

92
rookie

Devrait ressembler à ceci:

class Number 
{
    public:
        Number& operator++ ()     // prefix ++
        {
           // Do work on this.   (increment your object here)
           return *this;
        }

        // You want to make the ++ operator work like the standard operators
        // The simple way to do this is to implement postfix in terms of prefix.
        //
        Number  operator++ (int)  // postfix ++
        {
           Number result(*this);   // make a copy for result
           ++(*this);              // Now use the prefix version to do the work
           return result;          // return the copy (the old) value.
        }
}; 
145
Martin York

La différence réside dans la signature que vous choisissez pour votre (vos) surcharge (s) de operator ++.

Cité de l'article pertinent sur ce sujet en C++ FAQ (allez-y pour plus de détails):

class Number {
  public:
    Number& operator++ ();     // prefix ++: no parameter, returns a reference
    Number  operator++ (int);  // postfix ++: dummy parameter, returns a value
};

P.S .: Lorsque j'ai découvert cela, tout ce que je voyais au départ était le paramètre factice, mais les différents types de retour sont en réalité plus intéressants. ils pourraient expliquer pourquoi ++x est considéré comme plus efficace que x++en général _.

31
stakx

Vous avez deux façons de surcharger les deux opérateurs (prefix/postfix) ++ pour un type T:

Méthode d'objet:

C’est le moyen le plus simple d’utiliser un idiome "commun" OOP.

class T
{
    public :
        T & operator++() // ++A
        {
            // Do increment of "this" value
            return *this ;
        }

        T operator++(int) // A++
        {
           T temp = *this ;
           // Do increment of "this" value
           return temp ;
        }
} ;

Fonction non membre de l'objet:

C'est une autre façon de procéder: tant que les fonctions se trouvent dans le même espace de noms que l'objet auquel elles font référence, elles seront prises en compte lorsque le compilateur cherchera une fonction permettant de gérer le code ++t ; ou t++ ;:

class T
{
    // etc.
} ;


T & operator++(T & p_oRight) // ++A
{
   // Do increment of p_oRight value
   return p_oRight ;
}

T operator++(T & p_oRight, int) // A++
{
   T oCopy ;
   // Copy p_oRight into oCopy
   // Do increment of p_oRight value
   return oCopy ;
}

Il est important de se rappeler que, d'un point de vue C++ (y compris un point de vue du compilateur C++), ces fonctions non membres font toujours partie de l'interface de T (tant qu'elles se trouvent dans le même espace de noms).

La notation de fonction non membre présente deux avantages potentiels:

  • Si vous parvenez à les coder sans les rendre amis de T, vous augmentez l'encapsulation de T
  • vous pouvez l'appliquer même à des classes ou des structures dont vous ne possédez pas le code. C'est un moyen non intrusif d'améliorer l'interface d'un objet sans modifier sa déclaration.
14
paercebal

Je sais qu'il est tard, mais j'ai eu le même problème et j'ai trouvé une solution plus simple. Ne vous méprenez pas, c'est la même solution que celle du haut (publié par Martin York). C'est juste un bit plus simple. Juste un peu. C'est ici:

class Number
{
        public:

              /*prefix*/  
        Number& operator++ ()
        {
            /*Do stuff */
            return *this;
        }

            /*postfix*/
        Number& operator++ (int) 
        {
            ++(*this); //using the prefix operator from before
            return *this;
        }
};

La solution ci-dessus est un peu plus simple car elle n’utilise pas d’objet temporaire dans la méthode postfix.

0
X. Mora

Déclare comme ça:

class A
{
public:
    A& operator++();    //Prefix (++a)
    A operator++(int); //Postfix (a++)

};

Implémentez correctement - ne jouez pas avec ce que tout le monde sait qu'ils font (incrémenter puis utiliser, utiliser puis incrémenter).

0
Kate Gregory