Overloaded + operator - adding int to an object?

Below is a program that tests several overloaded operators. The comments are not mine, but added in by my professor.

I understand the program quite well, but I just have one question about the code below.

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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include <iostream>
using namespace std;

class Length
{
private:
    int len_inches;
public:
    Length(int feet, int inches)
    {
        setLength(feet, inches);
    }
    Length(int inches){ len_inches = inches; }
    int getFeet() const { return len_inches / 12; }
    int getInches() const { return len_inches % 12; }
    void setLength(int feet, int inches)
    {
        len_inches = 12 *feet + inches;
    }
    // Overloaded arithmetic and relational operators
    friend Length operator+(Length a, Length b);
    friend Length operator-(Length a, Length b);
    friend bool operator<(Length a, Length b);
    friend bool operator==(Length a, Length b);

};

int main()
{
    Length first(0), second(0), third(0);
    int ft, in;

    cout << "Enter a distance in feet and inches: ";
    cin >> ft >> in;
    first.setLength(ft, in);
    cout << "Enter another distance in feet and inches: ";
    cin >> ft >> in;
    second.setLength(ft, in);

    //Test the + and - operators

    third = first + second;
    cout << "The result of adding first and second is ";
    cout << third.getFeet() << " feet, ";
    cout << third.getInches() << " inches.\n";
    third = first - second;
    cout << "The result of subtracting first minus second is ";
    cout << third.getFeet() << " feet, ";
    cout << third.getInches() << " inches.\n";

    // Add an integer
    third = 2 + second;
    cout << "The result of 2 + second is ";
    cout << third.getFeet() << " feet, ";
    cout << third.getInches() << " inches.\n";

    // Use relational operators
    if (first == second)
	cout << "First is equal to second.\n";
    if (first < second)
	cout << "First is less than second.\n";
    else
	cout << "First is greater than second.\n";
		
    return 0;
}


//*************************************
// Overloaded operator +              *
//*************************************
Length operator+(Length a, Length b)
{
    return Length(a.len_inches + b.len_inches);
}

//*************************************
// Overloaded  operator -             *
//*************************************
Length operator-(Length a, Length b)
{
    return Length(a.len_inches - b.len_inches);
}

//************************************
// Overloaded operator ==            *
//************************************
bool operator==(Length a, Length b)
{
    return a.len_inches == b.len_inches;
}

//************************************
// Overloaded operator <             *
//************************************
bool operator<(Length a, Length b)
{
    return a.len_inches < b.len_inches;
}


The only thing I dont understand is the following statement:
third = 2 + second; (line 52)

How does the compiler understand this? Does it pass 'second' as Length b, and 2 as Length a (thus implicitly converting the integer 2 to an object of type Length)? In that case, how does the statement 'a.len_inches' make any sense?

The professor has overloaded the operator in a way that 2 is added to the number of inches. So if 'second' contains 10 inches, then 2 + second will result in 12 inches.

But im confused about how the compiler adds an int to an object.
Last edited on
Length(int inches){ len_inches = inches; }; is a converting constructor.
http://en.cppreference.com/w/cpp/language/converting_constructor


third = 2 + second;

a. construct an anonymous temporary object of type Length; direct-initialization via Length::Length(int)

b. call Length::operator+( anonymous_temporary_object, second );

c. destroy the anonymous temporary object

Note: copy elision may be (usually would be) applied http://en.cppreference.com/w/cpp/language/copy_elision
Okay, so I was right. The 2 is converted to type Length.

But still, how does the compiler interpret "a.len_inches" when 2 is passed in? Is it because len_inches is the only member variable, so the compiler interprets that as "2 inches + b.len_inches"?

What if there were multiple member variables?
Last edited on
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
#include <iostream>

static int n = 0 ;

struct Length
{
     Length( int v ) : value(v)
     { std::cout << ++n << ". construct: object at: " << this << " value == " << v << '\n' ; }

     ~Length()
     { std::cout << ++n << ".   destroy: object at: " << this << " value == " << value << '\n' ; }

     int get() const
     { std::cout  << ++n << ".      get: object at: " << this << " return value == " << value << '\n' ; return value ; }

     private:
         int value ;
         int another_variable = 999 ; // a second member variable (for exposition)
};

Length operator+ ( const Length& a, const Length& b )
{
    std::cout << ++n << ". operator+: object a is at: " << std::addressof(a)
              << " and object b is at: " << std::addressof(b) << '\n' ;

    std::cout << ++n << ". operator+: get the values from the two objects and sum them up\n" ;
    const int total = a.get() + b.get() ;
    std::cout << ++n << ". sum == " << total << '\n' ;

    std::cout  << ++n << ". operator+: return object constructed with the sum " << total << '\n' ;
    return total ;
}

int main()
{
    std::cout  << ++n << ". construct object a with value 6\n" ;
    const Length a = 6 ;

    {
        std::cout << ++n << ". this first constructs an anonymous object with value 2\n" ;
        const Length b = 2 + a ;
        std::cout << ++n << ". after destroy anonymous temporary object with value 2\n" ;
        std::cout << ++n << ". about to destroy object b\n" ;
    }

    std::cout << ++n << ". about to destroy object a\n" ;
}

1. construct object a with value 6
2. construct: object at: 0x7fff32eb3940 value == 6
3. this first constructs an anonymous object with value 2
4. construct: object at: 0x7fff32eb3930 value == 2
5. operator+: object a is at: 0x7fff32eb3930 and object b is at: 0x7fff32eb3940
6. operator+: get the values from the two objects and sum them up
7.      get: object at: 0x7fff32eb3930 return value == 2
8.      get: object at: 0x7fff32eb3940 return value == 6
9. sum == 8
10. operator+: return object constructed with the sum 8
11. construct: object at: 0x7fff32eb3938 value == 8
12.   destroy: object at: 0x7fff32eb3930 value == 2
13. after destroy anonymous temporary object with value 2
14. about to destroy object b
15.   destroy: object at: 0x7fff32eb3938 value == 8
16. about to destroy object a
17.   destroy: object at: 0x7fff32eb3940 value == 6

http://coliru.stacked-crooked.com/a/141d99a4e8bae64f
@JLBorges:

Absolutely beautiful! Thank you for making it is easy to follow.

So to outline the steps:

(1) First temporary object is created (the 2 in this case).
(2) Operator+ called and sum returned
(3) Once sum of temp object and object is returned, it is 'assigned' to second object. That is, the second object is constructed.
(4) At this point, the temp object is destroyed, as its job is done.


So these were the 4 basic steps I was confused with, and now I understand them perfectly. Thank you again for helping me.
Topic archived. No new replies allowed.