Pouvons-nous surcharger operator++
pour pré-incrémentation et post-incrémentation? c'est-à-dire appeler SampleObject++
et ++SampleObject
les résultats sont corrects.
class CSample {
public:
int m_iValue; // just to directly fetch inside main()
CSample() : m_iValue(0) {}
CSample(int val) : m_iValue(val) {}
// Overloading ++ for Pre-Increment
int /*CSample& */ operator++() { // can also adopt to return CSample&
++(*this).m_iValue;
return m_iValue; /*(*this); */
}
// Overloading ++ for Post-Increment
/* int operator++() {
CSample temp = *this;
++(*this).m_iValue;
return temp.m_iValue; /* temp; */
} */
};
Nous ne pouvons pas surcharger une fonction basée uniquement sur le type de retour, et même si nous la prenons comme autorisée, elle ne résout pas le problème en raison de l'ambiguïté dans la résolution des appels.
Étant donné que la surcharge de l'opérateur est fournie pour que les types intégrés se comportent comme des types définis par l'utilisateur, pourquoi nous ne pouvons pas utiliser simultanément l'incrémentation pré et post pour nos propres types.
La version postfixe de l'opérateur d'incrémentation prend un paramètre fictif int
afin de lever l'ambiguïté:
// prefix
CSample& operator++()
{
// implement increment logic on this instance, return reference to it.
return *this;
}
// postfix
CSample operator++(int)
{
CSample tmp(*this);
operator++(); // prefix-increment this instance
return tmp; // return value before increment
}
Le modèle standard pour le pré-incrément et le post-incrément pour le type T
T& T::operator++() // pre-increment, return *this by reference
{
// perform operation
return *this;
}
T T::operator++(int) // post-increment, return unmodified copy by value
{
T copy(*this);
++(*this); // or operator++();
return copy;
}
(Vous pouvez également appeler une fonction commune pour effectuer l'incrémentation, ou si c'est une simple ligne comme ++ sur un membre, faites-le simplement dans les deux)
pourquoi nous ne pouvons pas bénéficier à la fois de pré et post-incrémentation pour nos propres types en même temps.
Vous pouvez:
class CSample {
public:
int m_iValue;
CSample() : m_iValue(0) {}
CSample(int val) : m_iValue(val) {}
// Overloading ++ for Pre-Increment
int /*CSample& */ operator++() {
++m_iValue;
return m_iValue;
}
// Overloading ++ for Post-Increment
int operator++(int) {
int value = m_iValue;
++m_iValue;
return value;
}
};
#include <iostream>
int main()
{
CSample s;
int i = ++s;
std::cout << i << std::endl; // Prints 1
int j = s++;
std::cout << j << std::endl; // Prints 1
}
[N4687]
La fonction définie par l'utilisateur appelée operator ++ implémente l'opérateur prefix et postfix ++. Si cette fonction est une fonction membre non statique sans paramètre ou une fonction non membre avec un paramètre, elle définit l'opérateur d'incrémentation de préfixe ++ pour les objets de ce type. Si la fonction est une fonction membre non statique avec un paramètre (qui doit être de type int) ou une fonction non membre avec deux paramètres (dont le second doit être de type int), elle définit l'opérateur d'incrémentation postfix ++ pour les objets de ce type. Lorsque l'incrément postfix est appelé suite à l'utilisation de l'opérateur ++, l'argument int aura la valeur zéro [Exemple:
struct X {
X& operator++(); // prefix ++a
X operator++(int); // postfix a++
};
struct Y { };
Y& operator++(Y&); // prefix ++b
Y operator++(Y&, int); // postfix b++
void f(X a, Y b) {
++a; // a.operator++();
a++; // a.operator++(0);
++b; // operator++(b);
b++; // operator++(b, 0);
a.operator++(); // explicit call: like ++a;
a.operator++(0); // explicit call: like a++;
operator++(b); // explicit call: like ++b;
operator++(b, 0); // explicit call: like b++;
}
#include<iostream>
using namespace std;
class increment{
int a;
public:
increment(int x)
{ a=x; }
void operator ++(){
cout<<"pre-increment:";
cout<<++a;}
void operator ++(int){ /*post version of increment operator takes int as a dummy parameter*/
cout<<endl<<"post-increment:";
cout<<a++;}
};
int main(){
increment o1(4);
increment o2(4);
++o1; //pre-increment
o2++; //post-increment
}
SORTIE:
pré-incrément: 5
post-incrémentation: 4