operator overloading return question
verthex

I'm using codeblocks/mingw gcc as my compiler and for the following code I'm getting a warning.

#SelectExpand
1#include <iostream> 2 3 4class number 5{ 6 private: 7 8 int value; 9 10 public: 11 12 number(int value) 13 { 14 this->value = value; 15 } 16 number& operator++ (); 17 void operator++ (int); 18 void print(); 19}; 20number& number::operator++() 21{ 22 value++; 23} 24void number::operator++ (int) 25{ 26 ++value; 27} 28void number::print() 29{ 30 std::cout<<value<<std::endl; 31} 32int main() 33{ 34 number eight(8); 35 eight++; 36 eight.print(); 37 ++eight; 38 eight.print(); 39 40 return 0; 41}

overloadplusminus.cpp|23|warning: no return statement in function returning non-void|

How come only one of the overloaded operators for ++ tell me that there is no return statement. I know that one is postfix and the other is prefix but why is there that preference. I actually don't need to return anything. I'm trying to make an iterator with this.

Heres a link to parashit

EDIT::NM I just realized there is a type number in front of the declaration for the function thats supposed to return a type number and the other one is type void.

Mark Oates
Quote:

Heres a link to parashit [www.parashift.com]

;D

flowbsd

operator++() is prefix and operator++(int) is postfix.

The ++ operation should return the object itself.

Your code works fine with no errors or warnings. I test it with both clang++ and g++.

verthex
number& number::operator++()
{
  value++;
}

This doesn't return anything.

Edgar Reynaldo

postfix should return a copy of *this before it is incremented. Otherwise you just used prefix.

Audric

This looks like an issue of learning a C++ subtlety that's rarely used (operator overloading), while the basics of the language are still not clear.

i++ evaluates to "the value of i before incrementation"
++i evaluates to "the value of i after incrementation"
i=5 evaluates as five.

verthex

postfix should return a copy of *this before it is incremented. Otherwise you just used prefix.

Actually no try this one.

#SelectExpand
1#include <iostream> 2 3 4class number 5{ 6 private: 7 8 int value; 9 10 public: 11 12 number(int value) 13 { 14 this->value = value; 15 } 16 void operator++(); 17 void operator++(int); 18 void operator--(); 19 void operator--(int); 20 void print(); 21}; 22void number::operator++()//prefix 23{ 24 std::cout<<"1"<<std::endl; 25 value++; 26} 27void number::operator++ (int)//postfix 28{ 29 std::cout<<"2"<<std::endl; 30 ++value; 31} 32void number::operator--()//prefix 33{ 34 std::cout<<"3"<<std::endl; 35 value--; 36} 37void number::operator-- (int)//postfix 38{ 39 std::cout<<"4"<<std::endl; 40 --value; 41} 42void number::print() 43{ 44 std::cout<<value<<std::endl; 45} 46int main() 47{ 48 number eight(8); 49 eight++; 50 eight.print(); 51 ++eight; 52 eight.print(); 53 eight--; 54 eight.print(); 55 --eight; 56 eight.print(); 57 58 return 0; 59}

Audric said:

This looks like an issue of learning a C++ subtlety that's rarely used (operator overloading), while the basics of the language are still not clear.

Its meant to be used for iterating a list.

Audric
verthex said:

Its meant to be used for iterating a list.

Even if you only use it in a for(;;num++) loop, there's very little difficulty in letting it evaluate as the right value for a ++ operator.
ie. You should make this compile and run with the expected results:

number eight(8);
height.print(); // expected: 8
(eight++).print(); // expected: 8
(++eight).print(); // expected: 10

verthex
Audric said:

Even if you only use it in a for(;;num++) loop, there's very little difficulty in letting it evaluate as the right value for a ++ operator.
ie. You should make this compile and run with the expected results:

I'm not sure what you're saying, is the code correct or do I need to fix something?

EDIT:: I tried to compile the code but it wont compile

(eight++).print(); // expected: 8

I'm not sure how to overload parenthesis.

I'm also not sure how this would work in this case:

(eight++)->print(); // expected: 8

In case eight is pointer.

l j

Your ++ operators should return *this;
That should solve it.

Audric

For all numeric types, foo++ and ++foo HAVE a value. If you overload these operators without returning anything...it's misleading. Your overloads are limited, they can be used only if the calling code discards the value.

People expect that any piece of code written like:

number eight(8);
++eight;
eight.print(); // prints 9

is 100% identical to:

number eight(8);
(++eight).print(); // prints 9

With your class, the second form cannot be used at all (it just doesn't compile) because your overloads don't return a number.
(edit for clarity ) If you make your two overloads return a 'number' they will work both when the value is used, and when it's discarded.

I found an example at the bottom of the following page: http://www.cs.bu.edu/teaching/cpp/overload/incr-op.html

Clock Clock::operator++() // prefix form
{
  tick();
  return *this;
}

Clock::operator++(int) // postfix form
{
  Clock c = *this; // Makes a backup of the current instance
  tick();
  return c; // returns the value of the backup
}

Edgar Reynaldo
verthex said:

Actually no try this one.

Actually, no try this with your code :

#SelectExpand
1class number { 2 3/*.......*/ 4 5 friend ostream& operator<<(ostream& os , const number& n); 6}; 7 8ostream& operator<<(ostream& os , const number& n) { 9 os << n.value; 10 return os; 11} 12 13number n(5); 14 15cout << n << endl; 16cout << ++n << endl; 17cout << n++ << endl;

verthex

Alright guys, tell me whats wrong with this one.

#SelectExpand
1#include <iostream> 2 3 4class number 5{ 6 private: 7 8 int value; 9 10 public: 11 12 number(int value) 13 { 14 this->value = value; 15 std::cout<<value<<std::endl; 16 } 17 number operator++(); 18 number operator++(int); 19 void operator--(); 20 void operator--(int); 21 void print(); 22}; 23number number::operator++()//prefix 24{ 25 std::cout<<"1"<<std::endl; 26 value++; 27 return *this; 28} 29number number::operator++ (int)//postfix 30{ 31 std::cout<<"2"<<std::endl; 32 ++value; 33 return *this; 34} 35void number::operator--()//prefix 36{ 37 std::cout<<"3"<<std::endl; 38 value--; 39} 40void number::operator-- (int)//postfix 41{ 42 std::cout<<"4"<<std::endl; 43 --value; 44} 45void number::print() 46{ 47 std::cout<<value<<std::endl; 48} 49int main() 50{ 51 /* 52 number eight(8); 53 eight++; 54 eight.print(); 55 ++eight; 56 eight.print(); 57 eight--; 58 eight.print(); 59 --eight; 60 eight.print(); 61 */ 62 number eight(8); 63 64 eight.print(); // expected: 8 65 (eight++).print(); // expected: 8 66 (++eight).print(); // expected: 10 67 68 return 0; 69}

So when I use:

return *this;

that returns an instance, object, pointer to what exactly?
The address of the number class in memory, am I correct?

Thomas Fjellstrom

this is a pointer. *this is the object itself.

You didn't make those methods return a reference, you just made them return a copy of the object, which isn't that useful. There is a slight difference in the method prototypes they gave, and the ones you pasted.

verthex said:
number& number::operator++()
{
  value++;
}

This doesn't return anything.

Probably because you didn't return anything.

verthex

There is a slight difference in the method prototypes they gave, and the ones you pasted.

But this is the same thing I'm doing.

Their code.

Number ans = *this;
   ++(*this);  // or just call operator++()
   return ans;

my code.

#SelectExpand
1#include <iostream> 2 3 4class number 5{ 6 private: 7 8 int value; 9 10 public: 11 12 number(int value) 13 { 14 this->value = value; 15 std::cout<<value<<std::endl; 16 } 17 number operator++(); 18 number operator++(int); 19 void operator--(); 20 void operator--(int); 21 void print(); 22}; 23number number::operator++()//prefix 24{ 25 std::cout<<"1"<<std::endl; 26 value++; 27 28 number ans = *this; 29 ++((this)->value); // or just call operator++() 30 return ans; 31} 32number number::operator++ (int)//postfix 33{ 34 std::cout<<"2"<<std::endl; 35 ++value; 36 return *this; 37} 38void number::operator--()//prefix 39{ 40 std::cout<<"3"<<std::endl; 41 value--; 42} 43void number::operator-- (int)//postfix 44{ 45 std::cout<<"4"<<std::endl; 46 --value; 47} 48void number::print() 49{ 50 std::cout<<value<<std::endl; 51} 52int main() 53{ 54 /* 55 number eight(8); 56 eight++; 57 eight.print(); 58 ++eight; 59 eight.print(); 60 eight--; 61 eight.print(); 62 --eight; 63 eight.print(); 64 */ 65 number eight(8); 66 67 eight.print(); // expected: 8 68 (eight++).print(); // expected: 8 69 (++eight).print(); // expected: 10 70 71 return 0; 72}

Except their example doesn't specify what exactly they are incrementing. I have a type int called value. I rewrote the first method for the prefix ++ operation.

Quote:

You didn't make those methods return a reference, you just made them return a copy of the object, which isn't that useful.

Would this work?

number* ans = *this;
return *ans;

Thomas Fjellstrom
verthex said:

Would this work?

no.

Edgar Reynaldo

prefix increment and decrement should both return a number reference to *this.

postfix increment and decrement should both return a copy of *this made before this->value is incremented or decremented.

verthex

number reference to *this.

Can you show some code please.

Quote:

copy of *this made before this->value

Similarly to what I did except I didn't do it in the correct order?

Edgar Reynaldo
verthex said:

Can you show some code please.

#SelectExpand
1class number { 2public : 3 /// prefix 4 number& operator--(); 5 number& operator++(); 6 7 /// postfix 8 number operator--(int); 9 number operator++(int); 10}; 11 12/// prefix 13 14number& number::operator--() { 15 --value; 16 return *this; 17} 18 19number& number::operator++() { 20 ++value; 21 return *this; 22} 23 24/// postfix 25 26number number::operator--(int) { 27 number n = *this; 28 --value; 29 return n; 30} 31 32number number::operator++(int) { 33 number n = *this; 34 ++value; 35 return n; 36}

Quote:

Similarly to what I did except I didn't do it in the correct order?

Yes, the problem with yours was that you returned *this after incrementing this->value. That's not what postfix is supposed to do - it should give you the same value as the variable itself, and it can only do that if it returns a copy made before the incrementation takes place.

verthex

Thanks Edgar.

In the code:

number& number::operator--()

Is the ampersand used for passing the reference to *this?

Edgar Reynaldo
verthex said:

Is the ampersand used for passing the reference to *this?

Yes.
The ampersand literally means and reads 'reference'. A reference is used like a variable, but behind the scenes works like a pointer, allowing you to work directly on a variable from the same or a different scope.

void alter_copy(int a) {
   a = 5;// duh, only altered a local copy of a
}

void alter_reference(int& a) {
   a = 5;// Ooh, we actually altered the variable that was passed to us.
}

void alter_by_pointer(int* pa) {
   *pa = 5;// we used the address of a int variable to alter its value
           // same as reference alteration above, but we had to dereference
           // the pointer passed to us.
}

So when you return a reference, you are allowing the user to modify the variable you are returning to them, in this case, *this (the data pointed to by this). Fair warning - never return a reference to a stack object, because it goes out of scope and you are using deallocated memory.

Thomas Fjellstrom

You really should let him do his own research.

verthex

Yes.
The ampersand literally means and reads 'reference'. A reference is used like a variable, but behind the scenes works like a pointer, allowing you to work directly on a variable from the same or a different scope.

thanks for your help. Its everything I already knew but I wanted to be sure of.

Mark Oates
(return type) (function name) (function arguments)
{
   (process that includes arguments)
   return (return type);
}

Thread #609148. Printed from Allegro.cc