overloaded operators and conversions--Self-increment/self-decrement operator
Introduction:
Self-increment, the decrement operator is often implemented by classes such as iterators that provide pointers-like behavior to access elements in a sequence. For example, you can define a class that points to an array and provides an interview check for the elements in that array:
Class Checkedptr{public: //This class does not have a default constructor and must provide pointers to arrays. the/** constructor's parameters are two pointers: a pointer to the beginning of the array, and a pointer to the end of the array. * The constructor initializes the beg and end * with these two pointers and initializes the Curr to point to the first element */ checkedptr (int *b,int *e): Beg (b), End (e), Curr (b) {} Private: /** three members *beg: Point to the first element of the array; *end: Point to the end of the array; *curr: The array element that points to the current reference of the Checkedptr object. */ int *beg; int *end; int *curr;};
1 , define self-increment / self-decrement operator
"Best Practices"
C + + language does not require self-increment / The decrement operator must be a member of the class, but because these operators change the state of the operands , they are more likely to be members !
2 , pre-defined self-increment / self-decrement operator
The declaration of the prefix operator looks like this:
Class Checkedptr{public: checkedptr &operator++ (); Checkedptr &operator--();//as before};
"Best Practices"
to be consistent with the built-in type , the prefix operator should return a reference to the increment or decrement object .
The self-increment operator is based onEndCheckCurr,This ensures that the user cannotCurradded to the end of the array. The auto-subtract operation willCurrminus1and check if it will be reduced toBeg,AssumptionsCurrincrement to more thanEndorCurr Self-reductionmore thanBegjust throw aOut_of_rangeException:
Checkedptr &checkedptr::operator++ () { if (Curr = = end) { throw Out_of_range ("increment past the end of Checkedptr "); } + + Curr; return *this;} Checkedptr &checkedptr::operator--() { if (Curr = = Beg) { throw out_of_range ("decrement past the Beginning of Checkedptr "); } --Curr; return *this;}
3 , difference operator prefix and suffix form
The postfix operator function accepts an extra (that is, useless) int Shape participation. When using the postfix operator, the compiler provides 0 as the actual participation for this parameter. this int The only purpose of the formal participation is to make the suffix function different from the prefix function .
4 , define postfix operator
Class Checkedptr{public: checkedptr &operator++ (int); Checkedptr &operator--(int);//as before};
"Best Practices"
to be consistent with built-in operators, postfix operators should return old values [ i.e.: value not yet self-increment or decrement ] , and should be returned as a value, not a reference!
Checkedptr checkedptr::operator++ (int) { checkedptr ret (*this); + + *this; return ret;} Checkedptr checkedptr::operator--(int) { checkedptr ret (*this); --*this; return ret;}
object must be saved in addition 1/ minus 1 before the current state is saved, the operator calls its own prefix-type operator to add 1/ minus 1:
++*this;//--*this;
call this object's own already defined prefix self-increment/self-subtraction operators, those aboutCurris inBegand theEndrange of checks, and whether or not to throw an exception, they do it.o (∩_∩) o!
because you do not use int , so it's not named .
5 , explicit invocation of the self-increment / self-decrement operator
Suppose you want to use a function call to invoke a postfix operator, you must give an integer value:
Checkedptr Parr (ia,ia+ sizeof (IA)/sizeof (*ia)); parr.operator++ (); Explicitly call prefix parr.operator++ (0);//Explicit call suffix
The value passed is usually ignored , but the value is necessary to inform the compiler that the suffix version number is required!
"Best Practices"
In general, the best prefixes and suffixes are defined , and simply defining a prefix or simply defining a suffix class will make it strange for users accustomed to using both forms.
P449 Exercise 14.23~26 to review the previous sections of knowledge, because the knowledge points are relatively simple, so almost no gaze ... #include <iostream> #include <stdexcept>using namespace Std;class checkedptr{friend bool operator== (const CHECKEDPTR &lhs,const checkedptr &RHS); friend bool operator< (const CHECKEDPTR &lhs,const checkedptr &RHS); friend bool Operator> (const CHECKEDPTR &lhs,const checkedptr &RHS); Friend Checkedptr operator+ (const checkedptr &lhs,const size_t N); Friend Checkedptr operator-(const checkedptr &lhs,const size_t N); Friend ptrdiff_t operator-(const checkedptr &lhs,const checkedptr &RHS);p ublic:checkedptr (int *b,int *e): Beg (b ), End (e), Curr (b) {} checkedptr &operator++ (); Checkedptr &operator--(); Checkedptr operator++ (int); Checkedptr operator--(int); int &operator[] (const size_t); const INT &operator[] (const size_t) const; int &operator* (); const int &operator* () Const;private:int *beg; int *end; Int*curr;}; Checkedptr operator+ (const checkedptr &rhs,const size_t N) {checkedptr ret (RHS); Ret.curr + = n; if (ret. Curr > Ret.end) {throw Out_of_range ("operator + out_of_range!"); } return ret;} Checkedptr operator-(const checkedptr &rhs,const size_t N) {checkedptr ret (RHS); Ret.curr-= n; if (Ret.curr < Ret.beg) {throw Out_of_range ("operator-out_of_range!"); } return ret;} ptrdiff_t operator-(const checkedptr &lhs,const checkedptr &rhs) {if (!) ( Lhs.beg = = Rhs.beg && Lhs.end = = rhs.end)) {throw Out_of_range ("operator-out_of_range!"); } return Lhs.curr-rhs.curr;} Inlinebool operator== (const checkedptr &lhs,const checkedptr &rhs) {return Lhs.beg = Rhs.beg && lhs.cu rr = = Rhs.curr && Lhs.end = = rhs.end;} Inlinebool operator!= (const checkedptr &lhs,const checkedptr &RHS) {return! LHS = = RHS);} Inlinebool operator< (const checkedptr &lhs,const CHECKedptr &rhs) {return Lhs.beg = = Rhs.beg && lhs.end = rhs.end && Lhs.curr < Rhs.curr;} Inlinebool operator>= (const checkedptr &lhs,const checkedptr &RHS) {return! LHS < RHS);} Inlinebool operator> (const checkedptr &lhs,const checkedptr &rhs) {return Lhs.beg = = Rhs.beg && lhs. End = = Rhs.end && lhs.curr > Rhs.curr;} Inlinebool operator<= (const checkedptr &lhs,const checkedptr &RHS) {return! LHS > RHS); Or:return LHS = = RHS | | LHS < RHS;} int &checkedptr::operator* () {if (Curr = = end) {Throw Out_of_range ("Error pointer!"); } return *curr;} const int &checkedptr::operator* () const{if (Curr = = end) {Throw Out_of_range ("Error pointer!"); } return *curr;} int &checkedptr::operator[] (const size_t index) {if (Beg + index >= End | | Beg + Index < beg) {THR ow out_of_range ("index:out_of_range!"); } return * (Beg + index);} CoNST int &checkedptr::operator[] (const size_t index) const{if (Beg + index >= End | | Beg + Index < beg) { Throw Out_of_range ("index:out_of_range!"); } return * (Beg + index);} Checkedptr &checkedptr::operator++ () {if (Curr = = end) {Throw Out_of_range ("increment past the end of Ch Eckedptr "); } + + Curr; return *this;} Checkedptr &checkedptr::operator--() {if (Curr = = Beg) {throw Out_of_range ("decrement past the beginning of Checkedptr "); }--Curr; return *this;} Checkedptr checkedptr::operator++ (int) {CHECKEDPTR ret (*this); + + *this; return ret;} Checkedptr checkedptr::operator--(int) {CHECKEDPTR ret (*this); --*this; return ret;} Test int main () {int ia[] = {10,8,6,4,2,0}; Checkedptr Flag (Ia,ia + sizeof (IA)/sizeof (*ia)); For (Checkedptr Parr (Ia,ia + sizeof (IA)/sizeof (*ia)); Parr! = flag + sizeof (IA)/sizeof (*ia); Parr = Parr + 2) {cout << *parr << EndL } for (Checkedptr Parr (Ia,ia + sizeof (IA)/sizeof (*ia)); Parr! = flag + sizeof (IA)/sizeof (*ia); + + Parr) {cout << *parr << Endl; } checkedptr parr1 (Ia,ia + sizeof (IA)/sizeof (*ia)); cout << Endl << parr1[2] << Endl; cout << *parr1 << Endl; Checkedptr parr2 (Ia,ia + sizeof (IA)/sizeof (*ia)); + + parr2; cout << "parr1 <= parr2?" << (parr1 <= parr2) << Endl; return 0;}
C + + Primer Learning Note _61_ overloaded operators and conversions-self-increment/decrement operators