Reputation: 61
I have tried to find a solution in the internet,but I have always found examples where the classes, main function,etc are written in one file, not separated. Maybe it would be enough,but I am new in C++ and I guess my problem is different,because I use different header and source files for each classes and a different source file for main().
So, the problem is: I have tried to make printBoxMeretek(Box) function in Box2 class to be the friend function of Box class. It doesn't work and I don't know why. When I make the whole Box2 class to be friend of Box class, everything is ok. What should I do, if I want only printBoxMeretek(Box) function to be friend,not the whole Box2 class?
Anyway,the error message says that the problem is that boxSzelesseg and boxMagassag variables in Box class are private. But as I know a friend function should be able to handle private variables.
Here are the contents of my test files:
Box.h
#ifndef BOX_H
#define BOX_H
class Box
{
//friend function from Box2 [can be written anywhere: in private, in public,etc section] =>It does NOT work...why???
friend void printBoxMeretek(Box);
//make the whole Box2 class friend =>It works well.
// friend class Box2;
public:
};
#endif // BOX_H
Box2.h
#ifndef BOX2_H
#define BOX2_H
#include <iostream>
#include <Box.h>
class Box2
{
public:
void printBoxMeretek(Box)
{ }
};
#endif // BOX2_H
Thank you for your help.
Upvotes: 0
Views: 1044
Reputation: 25536
friend void printBoxMeretek(Box);
This declares a free function being friend of Box. You want a member function being friend, so you should declare a such:
class Box2;
class Box
{
friend void Box2::printBoxMeretek(Box);
};
Now problem is, you need the complete class declaration available for, so:
class Box;
class Box2;
{
public:
void printBoxMeretek(Box);
};
class Box
{
friend void Box2::printBoxMeretek(Box);
};
It does not matter if you have this in the same header or within two of them – the problem remains (i. e. you need to include Box2.h from Box.h).
Side note (thanks, Martin, for clarification): Even though a function is declared using Box
class, the complete definition of the class only needs to be available when you either define or call the function, so this works fine as it is. You just have to make sure to include both headers wherever you do one of these (or just always Box.h, which comes with Box2.h implicitly).
You might have preferred a reference, though. Your box classes do not look to me as if you really intended to copy them on each call to the print function:
void Box2::printBoxMeretek(Box const& b);
Upvotes: 3
Reputation: 29017
//friend function from Box2 [...] friend void printBoxMeretek(Box);
Because that is not the function from Box2
. Instead it is the declaration of a freestanding function in the global namespace ::printBoxMeretek
.
Instead what you need is:
friend void Box2::printBoxMeretek(Box);
... but to make that work, you will need to define Box2
first - so #include "Box2.h"
at the top of Box.h.
The final wrinkle, is that Box2.h can't include Box.h (otherwise you have a circular include). Fortunately you don't need to. Instead of #include "Box.h"
, just use class Box;
which declares the class (so you can use it as a function argument), but doesn't define it (so you can't create variables of type Box
).
So, Box2.h:
class Box;
class Box2 {
public:
void PrintBox(Box b);
};
Note that I have elided include guards. You want those.
Box.h:
#include "Box2.h"
class Box {
int v;
public:
Box(int v);
friend void Box2::PrintBox(Box b);
};
Box.cpp
#include "Box.h"
Box::Box(int v) : v(v) {}
Box2.cpp
#include "Box2.h" // Always put "our" header first to check it includes everything.
#include "Box" // Needed to define member function
#include <iostream>
Box2::PrintBox(Box b) {
std::cout << b.v << std::endl;
}
main.cpp
#include "Box.h"
int main() {
Box b(42);
Box2 b2;
b2.PrintBox(b);
return 0;
}
Upvotes: 2