Reputation: 11681
I came across the following code
class ExDer1 : public ExBase
{
public:
friend int Der1Fn()
{
....
}
};
I am a little confused here with
friend int Der1Fn()
{
//This has an implementation .Why is it a friend then ? since it can access the private/protected variables of the ExDer1 class ?
}
Normally I would expect to see something like the following
friend int Der1Fn(); //No implementation. Indicating that the Der1Fn is a method outside this class
which basically would mean that a function int Der1Fn()
would access the private variables of the class ExDer1. However this has an implementation. Could any one please explain what this means ?
Update:
So if I have the following code
class ExDer1 : public ExBase
{
public:
friend int Der1Fn()
{
std::cout << "Hello World";
}
};
int main()
{
Der1Fn(); // error C3767: 'Der1Fn': candidate function(s) not accessible
//.....
}
How do I call Der1Fn ?
Upvotes: 1
Views: 644
Reputation: 29764
Friend function ( or class) can be defined outside or inside class as well. If you define it inside you should provide matching declaration in correct scope, or argument dependent lookup will take place.
Following examples are logically same:
Example 1:
int Der1Fn();
class ExDer1 : public ExBase
{
public:
friend int Der1Fn()
{
....
}
};
Example 2 (recommended):
int Der1Fn()
{
....
}
class ExDer1 : public ExBase
{
public:
friend int Der1Fn();
};
How do I call Der1Fn ?
As simle as this.
Upvotes: 2
Reputation: 254771
You'd make a function a friend if it needs to access private members of the class, but shouldn't be a member. The friend function can be implemented either inside or outside the class.
If a friend function is declared (and defined) only within the class, then it's scoped within the surrounding namespace, as if you'd defined it there; but it can only be found by argument-dependent lookup (ADL) - that is, it can only be found if called with a type from the same namespace as one of its arguments.
In this case, the function has no arguments, so can't be found at all - which is why you can't call it from main
, or indeed from anywhere else. You'll need to declare the function outside the class, as well as in the friend declaration inside the class.
It would be more useful if it had an argument of the class type (or another type scoped in the same namespace); then it would be found when called with that argument type:
class ExDer1 : public ExBase
{
public:
friend int Der1Fn(ExDer1 const &)
{
....
}
};
int main()
{
ExDer1 obj;
Der1Fn(obj); // Found by ADL
}
Defining a friend inside a class is particularly useful for operator overloads which are (usually) only accessed by ADL anyway.
Upvotes: 1
Reputation: 4763
You can declare the body of the friend function inside the the class definition (like for any type of function).
However the friend function follows the same basic rules of every function ever implemented : it's a bad practice to declare it in the class definition (inlining , recompilations of all dependent objects on change etc) .
You referenced a MSDN example. They just made the example like to show how scoping is done. The function Der1Fn() is in the global namespace, not in the ExDer1::Der1Fn() .
For your updated post :
The class Der1Fn() doesn't have access to the ExDer1's this (it's not a part of the class, it's an external function, think of it as being static).
However, inside the Der1Fn()'s body you can access private member variables of ExDer1 type of objects.
Upvotes: 2