Meaning of the & in the Classes II example

In the Classes II example there is CVector&. I'm not sure exactly what the & means in this context. Is the overloaded operator expecting a constant object of type CVector to be passed by reference and and called param? Thanks for any help.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 // overloading operators example
#include <iostream>
using namespace std;

class CVector {
  public:
    int x,y;
    CVector () {};
    CVector (int a,int b) : x(a), y(b) {}
    CVector operator + (const CVector&);
};

CVector CVector::operator+ (const CVector& param) {
  CVector temp;
  temp.x = x + param.x;
  temp.y = y + param.y;
  return temp;
}

int main () {
  CVector foo (3,1);
  CVector bar (1,2);
  CVector result;
  result = foo + bar;
  cout << result.x << ',' << result.y << '\n';
  return 0;
}
closed account (L3UMSL3A)
Hey,

a reference (&) is an alias for an existing object. Meaning you can give an object as many names as you want:
1
2
3
4
int x;
int& another_name_for_x = x;
int& again_another_name_for_x = x;
int& a_third_alias_name_for_x = x;


Since a reference is an alias, no storage is allocated and no copy is made.
You use pass-by-reference, if you want to work with the original object (no copy, just alias name for the original object)
A const-reference (const CVector& in your example) means, that the original object cannot be changed.

Realize, that the const refers to the object behind the reference, not to the reference. A reference is always const since it can only refer to one object, you can't force a reference refering to another object.
I think I finally get this.

result = foo+bar;

...is actually 2 separate operations. 1st, the CVector object result is initialized with the values contained in the CVector object foo. That's why there's a naked x in the definition of the overloaded operator+ and why a reference to only one object needs to be passed to it. The 2nd operation is +bar. Then a 4th CVector object, temp, is instantiated to hold the result long enough to return it to the CVector object, result.

Man, I hope I finally followed the logic train into the station.
> 1st, the CVector object result is initialized with the values contained in the CVector object foo

No. First foo+bar is evaluated.
Then the result of the evaluation of foo+bar (the CVector object, temp) is assigned to result.

Noisy version of the same program:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>

class CVector {

  public:
    int x, y ;
    const char* name ;

    CVector( const char* name = "" ) : CVector(0,0,name) {};
    CVector( int a, int b, const char* its_name = "" ) : x(a), y(b), name(its_name) {

        std::cout << "construct CVector " << name << " {" << x << ',' << y << "}\n" ;
    }

    CVector operator + (const CVector&);
    CVector& operator = ( const CVector& that  ) {

        std::cout << "assign CVector " << that.name << " {" << that.x << ',' << that.y
                  << "} to CVector " << name << " (operator=)\n" ;
        x = that.x ;
        y = that.y ;
        return *this ;
    }
};

CVector CVector::operator+ (const CVector& param) {

    std::cout << "CVector " << name << " {" << x << ',' << y << "} + CVector "
              << param.name << " {" << param.x << ',' << param.y << "} (operator+)\n\t" ;

    CVector temp( x + param.x, y + param.y, "temp") ;
    std::cout << "\treturn temp\n" ;
    return temp ;
}

int main () {

  CVector foo (3,1,"foo");
  CVector bar (1,2,"bar");

  CVector result("result");

  std::cout << "\n........\nevaluate result = foo + bar;\n..........\n" ;
  result = foo + bar;
  std::cout << "........\n\n" ;

  std::cout << result.x << ',' << result.y << '\n';
}

construct CVector foo {3,1}
construct CVector bar {1,2}
construct CVector result {0,0}

........
evaluate result = foo + bar;
..........
CVector foo {3,1} + CVector bar {1,2} (operator+)
	construct CVector temp {4,3}
	return temp
assign CVector temp {4,3} to CVector result (operator=)
........

4,3

http://coliru.stacked-crooked.com/a/84899a20efe3ba98
That actually didn't help me to understand what's happening. If I take out all the text output and disregard the name being added to the objects, I still come down to the following 2 lines:

result = foo + bar; (which invokes the overloaded operator)

and

temp.x = x + param.x; (which adds the 2 numbers and assigns the result to temp.x)

What this makes me wonder is how x is being used without any qualification. It appears that only 1 object, param, is being passed. I assumed that to be the reference to bar, since it's on the right. That would make x the data from foo, also since it's on the left. I think I'm going to have to step this through the debugger to see what happens. If anyone can explain how we get data from 2 objects while passing only 1 reference, I'd be interested to hear it. It would really help me to understand how this is being accomplished.

Thanks again.

It appears that only 1 object, param, is being passed.

That's correct, however, CVector::operator+() is a member function. Implicitly x refers to this->x, and in this context *this refers to foo.

In function-call notation, result = foo + bar; is
result.operator=(foo.operator+(bar));
Last edited on
Thank you, mbozzi! That's really helping me make sense of it. So my 1st guess was pretty close to correct. result.operator= is a default copy constructor which acts 1st in order to have this->x to work with. Then (bar) is evaluated to provide param.x. Then, once all this is sorted out, x + param.x can be evaluated/executed and the sum assigned to temp.x. Then, finally, the values contained intemp are returned by operator+ to result.
Topic archived. No new replies allowed.