overloading operator+ confusion

Hi :)
Can someone explain me how this code works ?
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
#include <iostream>
using namespace std;
class test{
private:
	int num;
	int den;
public:
	test();
	test(int);
	test(int,int);
	void print();
	friend test operator+(const test&,const test&);
};

test::test(){}

test::test(int nnum) {
	num=nnum;
	den=1;
}

test::test(int nnum,int nden){
	num=nnum;
	den=nden;
}
void test::print(){
	cout<<"num: "<<num<<"  den: "<<den;
}
test operator+(const test& one,const test& two) {
	test toreturn(one.num+two.num,one.den+two.den);
	return toreturn;
}
	
int main() {
	test obj1(5);
	test obj2;
	obj2=obj1+1; //here
	obj1.print();
	cout<<endl;
	obj2.print();


	cin.ignore();
	return 0;
}

At line 37,class test hasn't got a operator+ with parameter test and int,alsotest operator+(const test&,int).
How does this work? The class has just one operator+ that takes two objects.Is the int converted to a test object? How?
If the class wouldn't have a constructor which has as parameters a int,the code wouldn't work...
Also is the constructor used here ? :| How does it apply ? Is there a rule or something ?

Thank you,have a nice evening :)
closed account (zb0S216C)
Guzfraba wrote:
"The class has just one operator+ that takes two objects."

The "test" class does not have a + operator; it allows a certain globally-overloaded + operator to access its data-members. In your code, a globally-overloaded + operator has been defined, but the arguments you've passed it do not correspond to the following declaration (so the compiler will attempt to call a suiting constructor of "test". See blow):

 
friend test operator+(const test&,const test&);

What you need to do is add another (or modify the original) declaration that supports the necessary operands:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Inside "test" class:
friend test operator + ( test const &, int const );

// Global name-space:
test operator + ( test const &Left_, int const Right_ )
  {
    return( ( Left_.num + Right_.num ), ( Left_.den + Right_.den ) );
  }

int main( )
  {
    test ObjectA_( 5 );
    ObjectA_ = ( ObjectA_ + 5 ); // Calls ::operator + ( test &, int );
  }

Granted, the compiler will implicitly convert the 1 on line 37 to a "test" instance, but it's best to support such trivial types, such as "int", in special cases. If this is not the behaviour you want, then declare the following constructor as "explicit":

 
explicit test::test(int nnum);


Guzfraba wrote:
"Is the int converted to a test object? How?"

When the compiler calls "::operator + ( test &, test & )" with 1 as the right-hand operand, the compiler will take the 1 and call the a constructor of "test" which accepts an "int" as a parameter.

Wazzak
Last edited on
ok,but the class test has got a constructor that takes 2 ints to,that means i can do something like this ?
obj2=obj1 + (4,7);
(4,7) is an expression (the comma operator) that have the result value of type int equal to 7. So when the compiler sees the line

obj2=obj1 + (4,7);

it considers it as an expression of the additive operator that have operands of types test and int that is as an expression

test + int

There is no such an operator- function in your program that has exactly these types of two parameters. So the compiler searches a more suitable function by trying to convert one of parameters to some other type.
Your class has the conversion constructor

test(int);

that converts an object of type int to an object of type test. So using this conversion constructor the compiler can convert the second argument of the expression

test + int

to type test. So the expression can be considered as

test + test

There is such an operator-function operator + in your program that accepts two arguments of type test. This operator-function will be called.
Last edited on
Topic archived. No new replies allowed.