Rajeshwar
Rajeshwar

Reputation: 11681

Friend function and implementation

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

Answers (3)

4pie0
4pie0

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

Mike Seymour
Mike Seymour

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

MichaelCMS
MichaelCMS

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

Related Questions