|
operator overloading return question |
verthex
Member #11,340
September 2009
|
I'm using codeblocks/mingw gcc as my compiler and for the following code I'm getting a warning. 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. 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
|
Quote: Heres a link to parashit [www.parashift.com]
-- |
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++.
____________________________________ |
verthex
Member #11,340
September 2009
|
number& number::operator++() { value++; } This doesn't return anything.
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
postfix should return a copy of *this before it is incremented. Otherwise you just used prefix. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
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" |
verthex
Member #11,340
September 2009
|
Edgar Reynaldo said: postfix should return a copy of *this before it is incremented. Otherwise you just used prefix. Actually no try this one. 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. number eight(8); height.print(); // expected: 8 (eight++).print(); // expected: 8 (++eight).print(); // expected: 10
|
verthex
Member #11,340
September 2009
|
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. 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
|
Your ++ operators should return *this;
|
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. 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
|
verthex said: Actually no try this one. Actually, no try this with your code : 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;
My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
verthex
Member #11,340
September 2009
|
Alright guys, tell me whats wrong with this one. 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?
|
Thomas Fjellstrom
Member #476
June 2000
|
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
Member #11,340
September 2009
|
Thomas Fjellstrom said: 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. 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
|
verthex said: Would this work? no. -- |
Edgar Reynaldo
Major Reynaldo
May 2007
|
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. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
verthex
Member #11,340
September 2009
|
Edgar Reynaldo said: 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
|
verthex said: Can you show some code please.
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. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
verthex
Member #11,340
September 2009
|
Thanks Edgar. In the code: number& number::operator--() Is the ampersand used for passing the reference to *this?
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
verthex said: Is the ampersand used for passing the reference to *this?
Yes. 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. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Thomas Fjellstrom
Member #476
June 2000
|
You really should let him do his own research. -- |
verthex
Member #11,340
September 2009
|
Edgar Reynaldo said: Yes. thanks for your help. Its everything I already knew but I wanted to be sure of.
|
Mark Oates
Member #1,146
March 2001
|
(return type) (function name) (function arguments) { (process that includes arguments) return (return type); }
-- |
|