Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » operator overloading return question

This thread is locked; no one can reply to it. rss feed Print
operator overloading return question
verthex
Member #11,340
September 2009
avatar

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
Member #1,146
March 2001
avatar

Quote:

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

;D

--
Visit CLUBCATT.com for cat shirts, cat mugs, puzzles, art and more <-- coupon code ALLEGRO4LIFE at checkout and get $3 off any order of 3 or more items!

AllegroFlareAllegroFlare DocsAllegroFlare GitHub

flowbsd
Member #13,650
October 2011

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++.

____________________________________
3D Egg | OpenGL Forum

verthex
Member #11,340
September 2009
avatar

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

This doesn't return anything.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Audric
Member #907
January 2001

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
Member #11,340
September 2009
avatar

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
Member #907
January 2001

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
Member #11,340
September 2009
avatar

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
Member #10,584
January 2009
avatar

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

Audric
Member #907
January 2001

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
Major Reynaldo
May 2007
avatar

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
Member #11,340
September 2009
avatar

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
Member #476
June 2000
avatar

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.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

verthex
Member #11,340
September 2009
avatar

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
Member #476
June 2000
avatar

verthex said:

Would this work?

no.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

verthex
Member #11,340
September 2009
avatar

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
Major Reynaldo
May 2007
avatar

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
Member #11,340
September 2009
avatar

Thanks Edgar.

In the code:

number& number::operator--()

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

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

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
Member #476
June 2000
avatar

You really should let him do his own research.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

verthex
Member #11,340
September 2009
avatar

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
Member #1,146
March 2001
avatar

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

--
Visit CLUBCATT.com for cat shirts, cat mugs, puzzles, art and more <-- coupon code ALLEGRO4LIFE at checkout and get $3 off any order of 3 or more items!

AllegroFlareAllegroFlare DocsAllegroFlare GitHub

Go to: