how to structure classes involving friend function

S

subramanian100in

The following post is for learning purpose only. I will try to avoid
friend functions and friend classes.

Consider the following piece of code:

class Test;

class Sample
{
public:
void friend_fn(const Test& ref);
// rest of the Sample class
};

class Test
{
public:
friend void Sample::friend_fn(const Test& ref);
// rest of the Test class
};

First approach:
We should structure the two class definitions only in the above
order(ie first the forward declaration of class Test followed by the
definition of class Sample and then the definition of class Test). Am
I correct ? If the two class definitions are kept in the above order
in the same header file, then there is no issue. But is it correct to
keep multiple class definitions in the same header file?

Now consider the following second approach:
Suppose I want to keep the definition of class Sample in, say,
Sample.h and the definition of class Test in Test.h. Also, suppose I
want to keep the function Sample::friend_fn() as an inline function.
Then the definition of Sample::friend_fn() should appear in Sample.h.
But the problem in this approach is that Sample::friend_fn() is going
to use some members of the class Test and we can only have a forward
declaration of class Test in Sample.h. My question: is this second
approach feasible ? If so, how to accomplish it ?

In real work environment, which approach is followed ? Kindly explain.

Thanks
V.Subramanian
 
Ö

Öö Tiib

Now consider the following second approach:
Suppose I want to keep the definition of class Sample in, say,
Sample.h and the definition of class Test in Test.h. Also, suppose I
want to keep the function Sample::friend_fn() as an inline function.
Then the definition of Sample::friend_fn() should appear in Sample.h.
But the problem in this approach is that Sample::friend_fn() is going
to use some members of the class Test and we can only have a forward
declaration of class Test in Sample.h. My question: is this second
approach feasible ? If so, how to accomplish it ?

In real work environment, which approach is followed ? Kindly explain.

Something is wrong with your design. You tie two classes with close,
inline level friendship. The classes can not be kept or used
separately after that. Tie together and keep together:

/// Sample_and_Test.hpp
class Test;

class Sample
{
public:
inline void friend_fn(const Test& ref);
// rest of the Sample class

};

class Test
{
public:
friend void Sample::friend_fn(const Test& ref);
// rest of the Test class

};

inline void Sample::friend_fn(const Test& ref)
{
// do your intimate stuff with ref
}
 
R

Robert Fendt

In real work environment, which approach is followed ? Kindly explain.

In the real world, you should probably avoid such 'design' at
all costs. Actually, it can never really work. If you use the
second class's interface in an inline function of the first
class, then the interface of the second class has to be known at
that point. So you have to include the complete class definition
beforehand.

Likewise, if the second class wants to use said inline function,
it has to know the complete class definition as well. This is a
'chicken or egg' kind of problem, and cannot be resolved without
some compromise.

The easiest way out would probably be to just use a saner design.
Class dependencies should form an acyclic graph (ideally a
tree). The acyclic property is crucial. If you have dependency
cycles like this, that's a sure sign there is something wrong
with your class structure.

If you can absolutely not avoid havinh dependency cycles (for
whatever reason), you have to use e.g. something like pointer to
implementation, which means you cannot keep everything inlined.

Regards,
Robert
 

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,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top