Hi friends,

I was understanding the concept of friend functions. I read in my book that there are two possible ways of "making friendship":cool:
1. Make a class a friend.
2. Make the method in a class a friend.

I am able to write a code for the first point. But when I tried the second one, I got the error as said in the title.

Here is my piece of code. To make this less lengthier I have put .h and .cpp file in one code block.

/****************** MyClass.h ***************/

#ifndef MYCLASS_H
#define MYCLASS_H


class MyClass
{
    public:
        MyClass();
        int GetprivVar1() { return privVar1; }
        //friend class FriendClass;
        friend void FriendClass::changeMyVariable(MyClass*);
    protected:
    private:
        int privVar1;
};

#endif // MYCLASS_H


/****************** MyClass.cpp ***************/

#include "../include/MyClass.h"

MyClass::MyClass()
{
    privVar1 = 0;
}
/****************** FriendClass.h ***************/

#ifndef FRIENDCLASS_H
#define FRIENDCLASS_H
#include "MyClass.h"

class FriendClass
{
    public:
        FriendClass();
        void changeMyVariable (MyClass *);
    protected:
    private:
};

#endif // FRIENDCLASS_H


/****************** FriendClass.cpp ***************/

#include "../include/FriendClass.h"

FriendClass::FriendClass()
{
    //ctor
}

void FriendClass::changeMyVariable(MyClass* obj)
{
    obj->privVar1 = 9;
}
#include <iostream>
#include "include/FriendClass.h"
#include "include/MyClass.h"

using namespace std;
int main()
{
    MyClass obj1;
    FriendClass obj2;
    cout<<"before : "<<obj1.GetprivVar1();
    obj2.changeMyVariable(&obj1);
    cout<<"after : "<<obj1.GetprivVar1();

    return 0;
}

Here I'm talking about lines 12 and 13 in first code block (MyClass.h).
If I make a class a friend it works, but making friendship with the function is giving compiler error

error: 'FriendClass' has not been declared

Recommended Answers

All 17 Replies

You need to "forward declare" FriendClass at the top of MyClass.h. On line 6, put class FriendClass; . This tells the compiler that such a thing exists so it doesn't complain when it runs into the symbol in the MyClass declaration.

You need to "forward declare" FriendClass at the top of MyClass.h. On line 6, put class FriendClass; .

Didn't work.

It's giving these errors.

error: invalid use of incomplete type 'struct FriendClass' (line 13 : MyClass.h)
error: forward declaration of 'struct FriendClass' (line 6 : MyClass.h)

How are you compiling these? As a project in an IDE or on the command line?

In FriendClass.h, dont include MyClass.h.

Instead specify that an object of MyClass exists

class MyClass;

The compiler gives you errors because it is unsure whether FriendClass has the Function in it.
Now as your main file is including both headers in the right order. It must work

@Jonsca : I'm compiling it using IDE - Code::Blocks. But what difference it makes
@Sky Diploma : Your suggestion didn't work. Giving the same error as I posted previously, but this time the error is on MyClass instead of FriendClass.

@Jonsca : I'm compiling it using IDE - Code::Blocks. But what difference it makes

If you were doing it on the command line the order of the files can matter. Let me pull your files into a project and see what happens.

Let me pull your files into a project and see what happens.

Thanks, That would be great...

I may have to recuse myself from this one and learn from whomever gets it right, because I've tried darn near everything. This is one of those "circular" situations where they both depend on each other (since you have the variable in FriendClass being passed as a reference to MyClass, and of course the friend function going in the other direction.

I am able to compile and link using g++, with changes below.

1. in FriendClass.h remove MyClass.h include and provide forward declaration for MyClass

2. In MyClass.h include FriendClass.h

I still get errors with that, even when I try to compile on the command line.

Invoking g++

FriendClass.cpp: In member function 'void FriendClass::changeMyVariable(MyClass*
)':
FriendClass.cpp:15:8: error: invalid use of incomplete type 'struct MyClass'
FriendClass.h:6:7: error: forward declaration of 'struct MyClass'

Within C::B

obj\Debug\main.o||In function `main':|
|9| undefined reference to `FriendClass::FriendClass()'|
|11|undefined reference to `FriendClass::changeMyVariable(MyClass|
||=== Build finished: 2 errors, 0 warnings (0 minutes, 3 seconds) ===|

Make sure the cpp include the header files of what is needed

I am able to compile and link using g++, with changes below.

1. in FriendClass.h remove MyClass.h include and provide forward declaration for MyClass

2. In MyClass.h include FriendClass.h

I too tried this, but same error. It'd be better if you could post your code.

g++ -Wall main.cpp myclass.cpp friendclass.cpp -o friend

#ifndef MYCLASS_H
#define MYCLASS_H

#include "friendclass.h"

class MyClass
{
    public:
        MyClass();
        int GetprivVar1() { return privVar1; }
        //friend class FriendClass;
        friend void FriendClass::changeMyVariable(MyClass*);
    protected:
    private:
        int privVar1;
};

#endif // MYCLASS_H
/****************** FriendClass.h ***************/

#ifndef FRIENDCLASS_H
#define FRIENDCLASS_H

class MyClass;

class FriendClass
{
    public:
        FriendClass();
        void changeMyVariable (MyClass *);
    protected:
    private:
};

#endif // FRIENDCLASS_H
/****************** MyClass.cpp ***************/

#include "myclass.h"

MyClass::MyClass()
{
    privVar1 = 0;
}
#include "friendclass.h"
#include "myclass.h"

FriendClass::FriendClass()
{
    //ctor
}

void FriendClass::changeMyVariable(MyClass* obj)
{
    obj->privVar1 = 9;
}
#include <iostream>
#include "friendclass.h"
#include "myclass.h"

using namespace std;
int main()
{
    MyClass obj1;
    FriendClass obj2;
    cout<<"before : "<<obj1.GetprivVar1();
    obj2.changeMyVariable(&obj1);
    cout<<"after : "<<obj1.GetprivVar1();

    return 0;
}

g++ -Wall main.cpp myclass.cpp friendclass.cpp -o friend

I have never done the compilation from the command line. Does this order make a difference?
If then that should be my problem cos I'm doing from an IDE.

code is simple should work either way

thanks for all your help. i'll check out this problem with my colleagues on monday... till then i'll mark this as solved

Please post their recommendation if they have one.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.