2

Just read about friend functions and I'm trying to access private variable "number" in class A with friend function "Print" from class B. I'm working with Visual Studio. Compilation of my code gives me plenty of various errors like:

C2011: 'A' : 'class' type redefinition
C2653: 'B' : is not a class or namespace name

Please be patient with me me and show a proper way of achieving my goal.

Here are my files A.h:

class A
{
public:
    A(int a);
    friend void B::Print(A &obj);
private:
    int number;
};

A.cpp:

#include "A.h"

A::A(int a)
{
    number=a;
}

B.h:

#include <iostream>
using namespace std;
#include "A.h"
class B
{
public:
    B(void);
    void Print(A &obj);
};

B.cpp:

#include "B.h"

B::B(void){}

void B::Print(A &obj)
{
    cout<<obj.number<<endl;
}

main.cpp:

#include <iostream>
#include <conio.h>
#include "B.h"
#include "A.h"

void main()
{
    A a_object(10);
    B b_object;
    b_object.Print(A &obj);
    _getch();
}
3
  • 2
    tip: class B doesn't actually need to know the details of A, all it needs to know is that class A exists. Commented Dec 14, 2012 at 19:09
  • remove friend void B::Print(A &obj);, add friend class B; or follow Mooning Ducks tip. Commented Dec 14, 2012 at 19:11
  • In B.h remove #include "A.h" and add class A; then add #include "A.h" in B.cpp Commented Dec 14, 2012 at 19:14

2 Answers 2

3

... Second you might need a forward declaration of class B in the A.h header file to refer B as a friend:

#ifndef _A_H_
#define _A_H_
class B;

class A
{
     friend class B;
};
#endif

UPDATE
I'm currently not so sure if it's possible to declare member functions as friends, I'll have a look.

It's not possible to create member function friend declarations, you can either declare global functions or whole classes as friend, see also: C++ ref, Friendship and inheritance.

In general it's not a good design idea to use friend at all, because it strongly couples the classes together. The better solution will be to couple interfaces (which don't need to be publicly visible anyways).
In rare cases it might be a good design decision but that almost always applies to internal details.

Sign up to request clarification or add additional context in comments.

2 Comments

Using friend isn't always bad. See parashift.com/c++-faq/friends-and-encap.html
@FredLarson Yes, I mentioned that Fred. Anyway it's already deprecated in UML and you can usually replace the need for friend declarations using either abstract (pure virtual) or static (template) interfaces. This might also give you the fine grained control over what exactly can be accessed by a 'friend' class or method.
1

First you need to put

#ifndef A_H
#define A_H
.... your A-class definition
#endif

in your A.h and analogous in B.h, so that multiple includes of the same file is prevented (that is your duplicate definition error)...

5 Comments

Or you can put "#pragma once" at the begining of your .h files.
No, please: remove the double underscores. Names that contain two underscores and names that begin with an underscore followed by a capital letter are reserved to the implementation. Don't use them.
@PRouleau Hmm. If you are in the Visual C++-World. Not sure wether gcc understands that?
Well, the OP didn't mention the code should be portable and it does use Visual Studio. As for GCC, it does understand it. See stackoverflow.com/questions/787533/… I prefer to use it because it is one line and have no chance to conflic with another header file.
I would add that the OP is starting with C++. Where should he learn that the #define with underscores are reserved? I searched "c++ #define" and it is not specified in its description. Of course, any good book or tutorial would mention the importance to use include guards, but not always about the reserved rules.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.