friend function problem

Jan 19, 2010 at 8:58am
hi everyone
i had a problem when implementing the friend function

why i can't compile the program when the friend function is written in the header files?
but i can successfully compile the program if i write the class function in the main program?

the header file (test.h) is the following code:
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
class test
{
    public:
    int a, b;
    test();
    test(int x, int y);

    friend ostream& operator<<(ostream out, test &x);
};

test::test()
{
    a = b = 0;
}

test::test(int x, int y)
{
    a = x;
    b = y;
}

ostream& operator<<(ostream out, test &x)
{
    out << "a = " << x.a << endl;
    out << "b = " << x.b << endl;

    return out;
}


the main program is as follow:
1
2
3
4
5
6
7
8
9
10
11
12
#include<iostream>
#include"test.h"

using namespace std;

int main()
{
    test a(3, 5);
    test b(4, 8);

    cout << a << b << endl;
}


can someone tell me if i am doing some mistake when implementing the friend function?
or is that i can't implement the friend function in the header file?

thanks
Jan 19, 2010 at 9:11am
ostream& operator<<(ostream out, test &x) should be
ostream& operator<<(ostream& out, const test &x)

If you only have one source file, it won't make a difference. If you have more than one, you'd expect it to compile but fail at link time with multiple definitions of ostream& operator<<(ostream& out, const test &x).

Jan 19, 2010 at 9:25am
just now i've tried to add the const but my compiler still can't compile it correctly?
why does it still can't compile?
is there something wrong with the source code??
Jan 19, 2010 at 10:26am
Did you change the friend declaration too?
friend ostream& operator<<(ostream& out, const test &x);
Jan 19, 2010 at 12:14pm
ya
i've changed the function prototype and the function

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
class test
{
    public:
    int a, b;
    test();
    test(int x, int y);

    friend ostream& operator<<(ostream out, const test &x);
};

test::test()
{
    a = b = 0;
}

test::test(int x, int y)
{
    a = x;
    b = y;
}

ostream& operator<<(ostream out, const test &x)
{
    out << "a = " << x.a << endl;
    out << "b = " << x.b << endl;

    return out;
}
Jan 19, 2010 at 1:26pm
You must pass the stream by reference, not by value. streams are not copyable

1
2
3
ostream& operator<<( ostream& out, const test& x ) {
    return out << "a = " << x.a << std::endl << "b = " << x.b" << std::endl;
} 
Jan 19, 2010 at 1:46pm
oo i see i go try it out
Jan 19, 2010 at 2:04pm
=.=''' i still got the same problem

my compiler said:

line 8 : 'ostream' is neither function nor member function; cannot be declared friend
line 8 : expected ';' before '&' token
line 22: expected constructor, destructor, or type conversion before '&' token
line 23: missing terminating " character
line 11: no match for 'operator<<' in 'std::cout << a'
Jan 19, 2010 at 2:13pm
Add #include <ostream> at the beginning of your test.h file, and use std::ostream instead of ostream.
Jan 19, 2010 at 2:20pm
??then do i need to delete the friend ostream& operator<<(ostream out, const test &x); in the class member?
Jan 19, 2010 at 2:23pm
You should put the specification of the class in .h file and the implementation in .cpp file.
Jan 19, 2010 at 2:28pm
Don't delet. Friend function is not a memeber of a class, but its declaration must be included in the class specification.
Jan 19, 2010 at 2:30pm
=.=''' i've tried to implement the .h file into the .cpp file but it still shows the same error
but if i tried to implement the class into the main program it compiles and works fine

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
#include<iostream>

using namespace std;

class test
{
    public:
    int a, b;
    test();
    test(int x, int y);

    friend ostream& operator<<( ostream& out, const test& x );
};

test::test()
{
    a = b = 0;
}

test::test(int x, int y)
{
    a = x;
    b = y;
}

ostream& operator<<( ostream& out, const test& x ) {
    return out << "a = " << x.a << std::endl << "b = " << x.b << std::endl;
}


int main()
{
    test a(3, 5);
    test b(4, 8);

    cout << a << b << endl;
}

//this works fine
//but if i separate the class to the .h file my compiler will said error 
Jan 19, 2010 at 2:34pm
have you done this way?

.h file

1
2
3
4
5
6
7
8
9
class test
{
    public:
    int a, b;
    test();
    test(int x, int y);

    friend ostream& operator<<( ostream& out, const test& x );
};


.cpp file

1
2
3
4
5
6
7
8
9
10
11
12
13
14
test::test()
{
    a = b = 0;
}

test::test(int x, int y)
{
    a = x;
    b = y;
}

ostream& operator<<( ostream& out, const test& x ) {
    return out << "a = " << x.a << std::endl << "b = " << x.b << std::endl;
}


and also don't forget to include necessary libraries.
Jan 19, 2010 at 2:38pm
ya i've tried already but my compiler is still saying the same error

by the way, the compiler i'm using is code block
Jan 19, 2010 at 3:18pm
i've tried to implement the .h file into the .cpp file but it still shows the same error
but if i tried to implement the class into the main program it compiles and works fine

Which is why I told you to replace ostream by std::ostream in your .h file....


To Van: Please don't confuse people. What you propose can obviously not compile as is.
Jan 19, 2010 at 11:48pm
o i see
now i can compile it successfully
special thanks lloydchristmas
and thanks to everyone that has help me to understand how to use friend function

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
//test.h file
class test
{
    public:
    int a, b;
    test();
    test(int x, int y);

    friend std::ostream& operator<<( std::ostream& out, const test& x );
};

test::test()
{
    a = b = 0;
}

test::test(int x, int y)
{
    a = x;
    b = y;
}

std::ostream& operator<<( std::ostream& out, const test& x )
{
    out << "a = " << x.a << std::endl << "b = " << x.b << std::endl;

    return out;
}


1
2
3
4
5
6
7
8
9
10
11
12
13
//main program
#include<iostream>
#include"test.h"

using namespace std;

int main()
{
    test a(3, 3);
    test b(4, 8);

    cout << a << b << endl;
}
Jan 20, 2010 at 12:00am
Another way to do is to add following lines in hpp file(new_file.hpp):
#include <iostream>
using namespace std ;


<CLASS DECLARATION>

CPP FILE will look like :-
#include <iostream>
#include "new_file.hpp"

<CLASS DEFINITION>
main() {
.....
}

Thanks
JySonia
Topic archived. No new replies allowed.