Problem with friend function and overloading operation

Hello people from cplusplus.com :)
I've got a problem and i really don't know why i have that problem.
I think everything must be fine but ... :X
Here is the whole code.
The program is simple.
It works with 2x2 matrices and it must use addition and calculate the determinant of matrix.
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
#include<iostream.h>

class Matrix {
private:
double a11,a12,a21,a22;
public:
Matrix() {a11=a12=a21=a22=0;}
Matrix(double x,double y,double v,double z) {a11=x;a12=y;a21=v;a22=z;}
Matrix(const Matrix &);
void SetValues(double x,double y,double v,double z) {a11=x;a12=y;a21=v;a22=z;}
double GetFirst() {return a11;}
double GetSecond() {return a12;}
double GetThird() {return a21;}
double GetFourth() {return a22;}
double CalculateDet();
friend Matrix operator+(Matrix);
};

Matrix::Matrix(const Matrix & p) {
a11=p.a11; a12=p.a12; a21=p.a21; a22=p.a22;}

double Matrix::CalculateDet() {
return a11*a22-a12*a21;}

Matrix operator+(Matrix a) {
 Matrix temp;
 temp.a11=a11+a.a11;
 temp.a12=a12+a.a12;
 temp.a21=a21+a.a21;
 temp.a22=a22+a.a22;
 return temp;
}

void main() {
Matrix A,B;
A.SetValues(1,2,3,4);
Matrix C(-2,3,7,5);
cout<<"a11: "<<A.GetFirst()<<endl;
cout<<"a12: "<<A.GetSecond()<<endl;
cout<<"a21: "<<A.GetThird()<<endl;
cout<<"a22: "<<A.GetFourth()<<endl;
cout<<"DetA: "<<A.CalculateDet()<<endl;
cout << "DetC: " << C.CalculateDet() << endl;
B=A+C;
cout<<"a11: "<<B.GetFirst()<<endl;
cout<<"a12: "<<B.GetSecond()<<endl;
cout<<"a21: "<<B.GetThird()<<endl;
cout<<"a22: "<<B.GetFourth()<<endl;
}


The problem is with a11 the compiler says that a11 is undeclared...
Please help :)
Oh... dear...

That should be int main(). void main() will not compile on GCC.

One solution is to have your operator take a second argument, Like:
Matrix operator+(Matrix b, Matrix a)
...and deal change all the solo a(int)s to b.a(int)s.
EDIT: Oh, also, be careful to redeclare your operator in your Matrix as well, else you'll get about 24 errors.

-Albatross
Last edited on
Dear Albatross

Could you explain me in details about this stuff:
"...and deal change all the solo a(int)s to b.a(int)s."
and "Oh, also, be careful to redeclare your operator in your Matrix as well, else you'll get about 24 errors."

Sorry im new to friend functions :X and they definetly are not very friendly :D
Ah... friends... if you declare something inside a class to be a "friend", that means that it can access all the private and protected members of that class, but you knew that.

When I said take all the solo stuff and change it, I mean change this:
1
2
3
4
5
6
7
8
Matrix operator+(Matrix a) {
 Matrix temp;
 temp.a11=a11+a.a11;
 temp.a12=a12+a.a12;
 temp.a21=a21+a.a21;
 temp.a22=a22+a.a22;
 return temp;
}

to this:
1
2
3
4
5
6
7
8
Matrix operator+(const Matrix &b, const Matrix &a) {
 Matrix temp;
 temp.a11=b.a11+a.a11;
 temp.a12=b.a12+a.a12;
 temp.a21=b.a21+a.a21;
 temp.a22=b.a22+a.a22;
 return temp;
}


Notice that the a11, a12, a21, and a22 that were originally on their own now have a b. preceding them.

Now that you changed the implementation of your operator, go back to your class and look for its declaration there. As you see, it takes only one argument. If you try to compile your code without changing that line to friend Matrix operator+(Matrix, Matrix);, you'll get about 24 errors, because it's giving a different operator that you didn't implement friend privileges. Not good; you need to make sure it's the operator you just implemented outside the class. Copying the line I just gave you should fix it.

EDIT: I hope this was sufficient for an explanation, though if you want to know more about friends...
http://cplusplus.com/doc/tutorial/inheritance/

EDIT2: Added &s, and dealt with some const correctness.

-Albatross
Last edited on
Sure they are... Their prototypes (in case of operator overloading) show the second/first argument explicitly, which would have been hidden when declaring them as members of the class itself...

For example your operator+:

Matrix operator+(Matrix);

vs

friend Matrix operator+(Matrix& a, Matrix& b); <- this should be the preferred method in this case, because it does not change the values of the class itself...


EDIT: oups... i came too late^^...
Last edited on
oups, certainly clear my minds.

For your topic , first of all ,the <iostream.h> is deprecated by the C++ standard, though i don't remember the exact time) and you should not use it any more ,instead ,using the following lines.
1
2
#include<iostream>
using namespace std;


Secondly,the choice between member method and just friend method outside the class regarding to operator +, in my practice , friend method is always preferred cause it is clearer, uh,at least for me.
Hope this helps you !
Thank to all of you for your help :)
I think that this problem is now solved ;)
Topic archived. No new replies allowed.