C + + Primer Learning Note _61_ overloaded operators and conversions-self-increment/decrement operators

Source: Internet
Author: User

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 &AMP;RHS);    friend bool operator< (const CHECKEDPTR &lhs,const checkedptr &AMP;RHS);    friend bool Operator> (const CHECKEDPTR &lhs,const checkedptr &AMP;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 &AMP;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 &AMP;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 &AMP;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 &AMP;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

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.