How to declare friend method when class definitions cross reference?

安稳与你 提交于 2019-12-13 06:24:48

问题


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?


回答1:


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;
}



回答2:


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).



来源:https://stackoverflow.com/questions/20772688/how-to-declare-friend-method-when-class-definitions-cross-reference

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!