Hi everyone I’m new to the forumn and programming – well iv’e read one book c++ programming in easy steps by Mike Mcgrath. I have now got a slightly more indepth book Sams teach yourself c++ in 24 hours fourth edition. All has been going well until I got upto hour 14 Operator overloading. I would be really grateful if someone could explain this concept in as simple terms as possible or help me try and understand the code bellow:

// Listing 14.2
 // Overloading the increment operator
 #include <iostream>
 
 class Counter
 {
 public:
     Counter();
     ~Counter(){}
     int GetItsVal()const { return itsVal; }
     void SetItsVal(int x) {itsVal = x; }
     void Increment() { ++itsVal; }
     const Counter& operator++ ();
 
 private:
     int itsVal;
 };
 
 Counter::Counter():
 itsVal(0)
 {}
 
 const Counter& Counter::operator++()
 {
     ++itsVal;
     return *this;
 }
 
 int main()
 {
     Counter i;
     std::cout << "The value of i is " << i.GetItsVal() 
         << std::endl;
     i.Increment();
     std::cout << "The value of i is " << i.GetItsVal() 
         << std::endl;
     ++i;
     std::cout << "The value of i is " << i.GetItsVal() 
         << std::endl;
     Counter a = ++i;
     std::cout << "The value of a: " << a.GetItsVal();
     std::cout << " and i: " << i.GetItsVal() << std::endl;
     return 0;
 }

The value of i is 0
The value of i is 1
The value of i is 2
The value of a: 3 and i:3

I understand the code i.e default constructor/destructor, getter and setter access methods and the increment function etc even though the setter is never used. What confuses me most I think is the actual layout of the operator function as the book doesn’t explain that at all. The code bellow is what confuses me the declaration and definition:

const Counter& operator++ ();

const Counter& Counter::operator++()

 {

     ++itsVal;

     return *this;

what happens in the simplest terms when ++i is first called? Is i passed into the parameters of the operator function directly or a copy of it? Is itsVal its member variable then incremented and a reference of it returned by the this pointer? Why is the this pointer used? And what happens when i is assigned to a – the operator is called again and i is passed in? and itsVal is incremented and a reference of it returned? Lol god I’m confused.

Any help in explaing this or links to good pages that explain this in simple terms would be much appreciated. Many thanks jimbob.

Recommended Answers

All 5 Replies

Think of the ++ operator as just another method of the class, like getItsVal() and setItsVal(). Instead of ++ another method of incrementItsVal() could have been written like this:


const Counter& Counter::incrementItsVal()
{
++itsVal;
return *this;
}


and used like this:

Counter i;
i.setItsVal(1);
i.incrementItsVal();

In theis case using the ++ operator is equivalent to, behaves the same way as, and is shorthand for incrementItsVal(). Which would you rather type:

++i;
or
i.incrementItsVal();

They mean the same thing.

>>Is itsVal its member variable then incremented and a reference of it returned by the this pointer?

Yes.

>>Why is the this pointer used?

Because this points to the address of i in this case, and in general, this points to the current object. In this case Counter is quite simple, and could have been replaced by a simple int variable. However, for teaching purposes, simple classes like this are frequently used. There will come a time when not so simple classes are used and the same approach can be used.

>>And what happens when i is assigned to a – the operator is called again and i is passed in?

All objects need a default constructor, a copy constructor, an assignment operator, and a destructor. If you don't explicitly create one, the compiler will do it for you. The compilers version of the assignment operator and the copy constructor will probably be a simple assignment of member variables from one object to another. This is often adequate, but not always, particularly if pointers are used as data members. In this case there is not copy constructor or assignment operator so a default version is made by the compiler.

In this line:

Counter a = ++i;

the = sign is really a placeholder and not an assignment operator. This line means increment the itsValue of i first, then return a reference to i, probably in the form of a temporary object. The temporary object is then used as the argument for the copy constructor which is used to create the Counter object called a. The itsValue of a will be the same as the itsValue of i. In essence, this line could be rewritten like this:

Counter a(++i);

but again, for readability purposes

Counter a = ++i;

is probably easier, so that's whats done.

It makes a lot more sense now all of a sudden it's helped me to understand the difference between using the prefix and post fix increment operators to least i'm 95 % i understand it fully lol thanx a lot for ur help.

To save me doing a new post on pretty much the same subject could you or anybody else who reads this thread check the comments on this code (sorry if i got a bit carried away with the comments lol) just to check I understand the code and whats going on correctly. I'm pretty sure i do just want to be 100%. plz feel free to correct me or give any useful comments. Many thanx again jimbobint.

#include <iostream>  
class Counter 
{
public:
     Counter();
     ~Counter(){}
     int GetItsVal()const { return itsVal; }
     void SetItsVal(int x) {itsVal = x; }
     const Counter& operator++ ();      // prefix
     const Counter operator++ (int); // postfix, the int is used as a signal or flag just to say this is the post fix operator nothing more.
private:
     int itsVal; 
};
Counter::Counter():  //default constructor initialises the itsval member to 0 
itsVal(0) 
{}
const Counter& Counter::operator++()   // prefix has no arguments
{
     ++itsVal;      // i's itsval member is incremented to 2 and then a reference to the object is returned by the this pointer
     return *this; 
}
const Counter Counter::operator++(int) 
{
     Counter temp(*this); // a temporary object or container holds the original value of i which is 0
     ++itsVal; // the itsval of i is then incremented to 1
     return temp; // the tempoary object is then returned. In the first call case it isn't used for anything.  
}                 // in the second call i's original value 3 is stored in the temporary object ,i's itsval is then incremented to 4, then the temporary object and original value stored there 3 is returned and assigned to counter a. 
int main() 
{
     Counter i;
     std::cout << "The value of i is " << i.GetItsVal() // A counter i is constructed with this initialised value of 0. i.GetItsVal returns that value in the counter. 
          << std::endl;
     i++;                                               // The post fix operator is called
     std::cout << "The value of i is " << i.GetItsVal() // GetItsVal returns itsval which has now had it's value incremented to 1
          << std::endl;
     ++i;                                               // the pre fix operator is then called on i
     std::cout << "The value of i is " << i.GetItsVal() // GetItsVal returns itsval which has now been incremented to 2 
          << std::endl;
     Counter a = ++i;                                   // the pre fix operator is called again i is incremented to 3 and a reference of the it  returned by the this pointer it is then assigned to counter a.
     std::cout << "The value of a: " << a.GetItsVal();  // GetitsVal is called on a and returns a's itsval memeber which has the same value as i's 3 as i was assigned to a.
     std::cout << " and i: " << i.GetItsVal() << std::endl; //GetItsVal returns i's itsval which has now been incremented to 3
     a = i++;                                               //the postfix operator is called on i 
     std::cout << "The value of a: " << a.GetItsVal();      //GetItsval is called on a which has been assigned i's original value before it was incremented and therefore returns the same value as before which is 3 
     std::cout << " and i: " << i.GetItsVal() << std::endl; //GetItsVal returns i's itsval which has now been incremented to 4
     return 0; 
}

The value of i is 0
The value of i is 1
The value of i is 2
The value of a: 3 and i: 3
The value of a: 3 and i: 4

Overall your comments seem on target. However, you seem to have some problem understanding the concept of the this pointer (I'm not absolutely sure I understand completely either, so don't worry too much about it). Basically, as I understand it, the this pointer is a pointer to the the object upon which the method is called. When you dereference the this pointer using the following syntax:

*this;

you are using the object itself, not a pointer to the object. Therefore the increment operator doesn't return the this pointer but the object itself. Behind the curtains of the compilers code, the object itself is changed into a reference to the object rather than the object. How the compiler transforms an object into a reference to the object I've never figured out. It's just something I've accepted. Pass an object to a function expecting a reference to an object of that type and it works. Return an object instead of a reference to an object of the same type and it works. Sheesh. I suspect there is a rational explanation and not genie behind the curtain, but it isn't explained in the books I have.

In your comments I would say the

a reference to the object is returned by dereferencing the this pointer

This is a minor nit pick, and has little, if anything, to do with understanding how the prefix and postfix increment operators work.

Glad I'm on the right track and yep the math behind the compiler and how it does what it does certainly seems a very interesting yet highly confusing thing. Thnx again jimbobint.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.