0

I want to define two classes, A and B. A has a data member which is a Class B object and is in-class initialised. A also has a method to retrieve the value in this B type data member and this method would be declared as a friend method in B. Here is my code:

class A{ public: int getBValue(); private: B b=B(1); }; class B{ public: friend int A::getBValue(); B(int i):value(i){} private: int value; }; int A::getBValue(){ return b.value; } 

And unsurprisingly the compilation had failed because of unknown type B in class A definition. I had tried to swap the definitions of A and B in the source and the result was even worse. Is there a possible way to resolve this cross reference issue between A and B?

3
  • What was the error when you declared B first? What happens if you only make the class 'A' as friend when switching the order? Anyway, why not have a public getter? Commented Dec 25, 2013 at 12:21
  • You can't make this without a compromise - either store a pointer to B instead of an instance and forward declare it, or give up on friend requirement and provide a getter instead. Commented Dec 25, 2013 at 12:27
  • @LaszloPapp Two errors. One is "use of undeclared identifier 'A'", the other is "'value' is a private member of 'B'". Commented Dec 25, 2013 at 13:10

2 Answers 2

3

If this is the complete code as you have it, then the problem is that the compiler doesn't know what a B is at the time it is compiling class A. One way to solve it is by creating a pointer to B instead of having a B itself:

A.h

#ifndef CLASS_A #define CLASS_A class B; class A{ public: int getBValue(); private: B *b; }; #endif 

B.h

#ifndef CLASS_B #define CLASS_B #include "A.h" class B{ public: friend int A::getBValue(); B(int i):value(i){} private: int value; }; #endif 

A.cpp

#include "A.h" #include "B.h" int A::getBValue(){ return b->value; } 
Sign up to request clarification or add additional context in comments.

Comments

0

Replacing an embedded member of type B with a pointer (or reference) to a B changes the way your class works and needs additional care when copying objects of class A.

When you reverse the definitions, you cannot make a member function of class A a friend of class B, because the type of A is incomplete at the time of the friend declaration. But you can make the entire class A a friend.

A solution with class A having an embedded member of class B could look like this:

class A; class B{ public: friend class A; B(int i):value(i){} private: int value; }; class A{ public: int getBValue(); private: B b=B(1); }; int A::getBValue(){ return b.value; } 

Changes made:

  1. Declared B before A. A forward declaration for A is used.
  2. Made the class A a friend of B. This works even when A is not yet fully defined.

Compiles with g++ version 4.7.2 (-std=c++11 needed for B b=B(1);)

Anyway, having a member of class A accessing a private member of class B is something which can (and should) almost always be avoided (see Laszlo Papp's comment on your post).

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.