【问题标题】:How to declare friend method when class definitions cross reference?类定义交叉引用时如何声明友元方法?
【发布时间】:2013-12-25 12:14:50
【问题描述】:

我想定义两个类,A 和 B。A 有一个数据成员,它是 B 类对象并且在类内初始化。 A 也有一个方法来检索此 B 类型数据成员中的值,并且此方法将在 B 中声明为友元方法。这是我的代码:

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

不出所料,编译失败是因为 A 类定义中的类型 B 未知。我曾尝试在源代码中交换 A 和 B 的定义,结果更糟。有没有办法解决 A 和 B 之间的交叉引用问题?

【问题讨论】:

  • 先声明B的时候报什么错?如果您在切换订单时仅将“A”类设为好友,会发生什么情况?无论如何,为什么不使用公共吸气剂?
  • @LaszloPapp 两个错误。一个是“使用未声明的标识符'A'”,另一个是“'value'是'B'的私有成员”。

标签: c++ friend-function


【解决方案1】:

如果这是您拥有的完整代码,那么问题是编译器在编译类A 时不知道B 是什么。解决它的一种方法是创建指向 B 的指针,而不是拥有 B 本身:

啊.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】:

    用指向B 的指针(或引用)替换B 类型的嵌入成员会改变您的类的工作方式,并且在复制A 类的对象时需要格外小心。

    当你反转定义时,你不能让类A的成员函数成为类B的朋友,因为A的类型在friend声明时是不完整的。但是你可以让整个班级A 成为朋友。

    A 的解决方案具有类B 的嵌入成员,可能如下所示:

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

    所做的更改:

    1. A 之前声明B。使用了 A 的前向声明。
    2. 使 A 成为 B 的朋友。即使 A 尚未完全定义,这也有效。

    使用 g++ 版本 4.7.2 编译(B b=B(1); 需要 -std=c++11)

    无论如何,让 A 类的成员访问 B 类的私有成员几乎总是可以(并且应该)避免(请参阅 Laszlo Papp 对您的帖子的评论)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-07
      • 2020-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-30
      相关资源
      最近更新 更多