private member functions as friends

D

Dan Smithers

Can a make a private member function a friend? The code below suggests
not. I am using g++ 4.2.3

I realise that I can make the whole CFriend class a friend, or make my
friend function public but I don't really want to do either.

thanks

dan


#include <iostream>

class CClass;

class CFriend
{
private:
CClass& my_target;
void myWork(void);
public:
CFriend(CClass& target):my_target(target){;}
virtual ~CFriend(void){;}

void work(void){return myWork();}
};

class CClass
{
private:
void doWork(void)
{
std::cout << " CClass doWork() my_val = " << my_val++ << std::endl;
}

int my_val;

public:
CClass(int val):my_val(val){;}
virtual ~CClass(void){;}

friend void CFriend::myWork(void);
};

void
CFriend::myWork(void)
{
my_target.doWork();
}

int
main(int argc, char *argv[])
{
CClass first(1);

CFriend second(first);

second.work();
}
 
P

puzzlecracker

Can a make a private member function a friend? The code below suggests
not. I am using g++ 4.2.3

I realise that I can make the whole CFriend class a friend, or make my
friend function public but I don't really want to do either.

thanks

dan

#include <iostream>

class CClass;

class CFriend
{
private:
CClass& my_target;
void myWork(void);
public:
CFriend(CClass& target):my_target(target){;}
virtual ~CFriend(void){;}

void work(void){return myWork();}

};

class CClass
{
private:
void doWork(void)
{
std::cout << " CClass doWork() my_val = " << my_val++ << std::endl;
}

int my_val;

public:
CClass(int val):my_val(val){;}
virtual ~CClass(void){;}

friend void CFriend::myWork(void);

};

void
CFriend::myWork(void)
{
my_target.doWork();

}

int
main(int argc, char *argv[])
{
CClass first(1);

CFriend second(first);

second.work();

}

Member functions cannot be friends. Only classes or user-defined
functions can be used as friends.
 
J

Jerry Coffin

Can a make a private member function a friend? The code below suggests
not. I am using g++ 4.2.3

Yes, you can -- but there are limitations that make what you're trying
to do unworkable.

[ ... ]
class CFriend
{
private:
CClass& my_target;
void myWork(void);

myWork is private -- so CClass has no access to it unless CFriend
declares (some part of) CClass to be a friend. It can't, however,
declare any _specific_ part of CClass as its friend, because all that's
visible of CClass at this point is a declaration, so the members of
CClass are currently unknown to the compiler.
public:
CFriend(CClass& target):my_target(target){;}
virtual ~CFriend(void){;}

void work(void){return myWork();}
};

class CClass
{
private:
void doWork(void)
{
std::cout << " CClass doWork() my_val = " << my_val++ << std::endl;
}

int my_val;

public:
CClass(int val):my_val(val){;}
virtual ~CClass(void){;}

friend void CFriend::myWork(void);

Here, you've tried to make use of the name myWork, which is not
accessible to CClass, because it's a private part of CFriend, and
CFriend hasn't declared CClass (or any part thereof) to be its friend.
Since the definition of CClass isn't visible until after the definition
of CFriend, CFriend can't refer directly to any member (public or
private) of CClass.

At least AFAIK, the only cure is something like:

class class1;

class class2 {
ret_type private();

friend class1;
};

class class1 {
// ...

friend ret_type class2::private();
};

You could arrange the classes in either order, but whichever one is
defined first will have to declare the entirety of the other as its
friend. The one that comes second can define only a specific member
function to be its friend.

Quite a few compilers have a mode to allow your original code even
though it's not technically allowed. You might want to look in the docs
to see if your compiler is among them.
 
D

Dan Smithers

Jerry said:
Can a make a private member function a friend? The code below suggests
not. I am using g++ 4.2.3

Yes, you can -- but there are limitations that make what you're trying
to do unworkable.

[ ... ]
class CFriend
{
private:
CClass& my_target;
void myWork(void);

myWork is private -- so CClass has no access to it unless CFriend
declares (some part of) CClass to be a friend. It can't, however,
declare any _specific_ part of CClass as its friend, because all that's
visible of CClass at this point is a declaration, so the members of
CClass are currently unknown to the compiler.
public:
CFriend(CClass& target):my_target(target){;}
virtual ~CFriend(void){;}

void work(void){return myWork();}
};

class CClass
{
private:
void doWork(void)
{
std::cout << " CClass doWork() my_val = " << my_val++ << std::endl;
}

int my_val;

public:
CClass(int val):my_val(val){;}
virtual ~CClass(void){;}

friend void CFriend::myWork(void);

Here, you've tried to make use of the name myWork, which is not
accessible to CClass, because it's a private part of CFriend, and
CFriend hasn't declared CClass (or any part thereof) to be its friend.
Since the definition of CClass isn't visible until after the definition
of CFriend, CFriend can't refer directly to any member (public or
private) of CClass.

At least AFAIK, the only cure is something like:

class class1;

class class2 {
ret_type private();

friend class1;
};

class class1 {
// ...

friend ret_type class2::private();
};

You could arrange the classes in either order, but whichever one is
defined first will have to declare the entirety of the other as its
friend. The one that comes second can define only a specific member
function to be its friend.

Quite a few compilers have a mode to allow your original code even
though it's not technically allowed. You might want to look in the docs
to see if your compiler is among them.

Thanks for the explanation. I suppose I never really considered that I
needed to be able to see the function to make it my friend.

If I make CFriend::myWork() public then it does work.

dan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,528
Members
45,000
Latest member
MurrayKeync

Latest Threads

Top