I've got a problem with friend functions in classes. Code:
1 2 3 4 5 6 7 8 9 10 11 12 13
class c2;
class c1 {
int i;
public:
void func();
friend c2::func();
}
class c2 {
int i;
public:
void func();
friend c1::func();
}
etc.
All I want is functions in each class having access to the private int from the other class. That doesn't seem to work, cause function in class c2 hasn't been declared, but I can't declare it before c1, cause member function cannot be declared outside the class and I can't define c2 before c1, cause there would be no way to define function from c1 as a friend of c2 class. That whole thing is some kind of paradox, I have no idea how to solve this.
I know that the problem can be solved using global functions or by defining the whole class as a friend, but I don't want to use that. I'm just wondering if there's a way to do it my way.
Strangely, I use friends almost exclusively to overload the output stream operator so I can print the class data members values out easily for easy debugging. I have not used it for other purposes though.
Just turn the member function c1::func() into a non-member function func(c1&). If you need access to private or protected elements of c1 make that function a friend of c1. Same with c2::func(). Hence this would look like
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
class c2;
class c1
{
public:
friendvoid func( c2 & );
friendvoid func( c1 & );
protected:
int i;
};
class c2
{
public:
friendvoid func( c2 & );
friendvoid func( c1 & );
private:
int i;
};
// forward declaration
class X;
// Is a friend of X and provides access to YFuncBase::func(), where func() is implemented.
class YFuncInterface
{
protected:
staticint &getI( X & x );
// maybe other functions to retrieve private or protected data from X.
};
class X
{
int i;
public:
void func();
friendclass YFuncInterface;
};
// Implements func() using functions from YFuncInterface
// to access protected and private members of X.
class YFuncBase : private YFuncInterface
{
public:
void func(); // can access X::i through YFuncInterface::getI().
};
// inherits func() from YFuncBase, bot not the access to protected
// and private members of X.
class Y : public YFuncBase
{
int i;
public:
friendvoid X::func();
};
// IMPLEMENTATION
int &YFuncInterface::getI( X & x )
{
return x.i;
}
void YFuncBase::func()
{
X x;
getI(x) = 0;
}
void X::func()
{
Y y;
y.i = 1;
}
A plus for this way of doing it, is that you have full control over the functions YFuncBase::func() can access. A minus is, that you have to explicitely specify them in the YFuncInterface.