【问题标题】:Reciprocal friend member functions = circular include declarations互惠的友元成员函数 = 循环包含声明
【发布时间】:2011-05-31 18:02:42
【问题描述】:

我在不同的 h 文件中定义了两个类,每个类都有一些私有函数。但是,我希望能够从另一个类中的函数访问每个类中的一个函数。

例如...

//apple.h:

class Beets;

class Apple
{
public:
    double  ShadeUsed();
private:
    void    Fruit();
    bool    RedRoots();
    friend  bool Beets::BlueRoots(); //<--- Error b/c not declared yet
};


//beets.h
#include "apple.h"

class Beets
{
    public:
    double  SunNeeded();
private:
    void    Leaves();
    bool    BlueRoots();
    friend  bool Apple::RedRoots();
};

目标是每个类中只有一个函数可以访问其他类的私有内容。例如,只有根函数才能访问其他类的私有内容。但是,如果不包含循环,我就无法实现互惠友谊。

我考虑过让整个 Beets 类成为 Apples 的朋友,这样类预声明就足够了,但我宁愿只允许一个函数私有访问。

有什么建议吗? 提前致谢, 马特。

(P.S.为什么每个“提前谢谢”,“Matt”之间的回车不会导致换行符?)

【问题讨论】:

  • 在回答您的 P.S. 时,您需要两个回车来生成换行符。哦,我正在闪回this question(简短的回答是你不能这样做)。
  • @Chris,我想我只需要声明整个班级为朋友。 @PS如果我做两个回车,它们之间就会有一整行。我只希望它们位于不同的行上。
  • 循环依赖通常是设计问题的征兆,我会尝试重构它以打破依赖关系。

标签: c++ friend circular-dependency


【解决方案1】:

您可以使用调用成员函数的友元函数。

//apple.h:

class Beets;

class Apple
{
public:
    double  ShadeUsed();
private:
    void    Fruit();
    bool    RedRoots();
    friend  bool Beets_BlueRoots(Beets* beets); 
    friend  bool Apple_RedRoots(Apple* apple);
};

bool Apple_RedRoots(Apple* apple);


//beets.h

class Beets
{
    public:
    double  SunNeeded();
private:
    void    Leaves();
    bool    BlueRoots();
    friend  bool Apple_RedRoots();
    friend  bool Beets_BlueRoots(Beets* beets);
};

bool Beets_BlueRoots(Beets* beets);

【讨论】:

  • 这是解决这个问题的正确方法。但是,根据 littleadv 的评论,我将更改课程,这样我就不需要使用朋友了。
【解决方案2】:

您似乎遇到了一些设计问题。我建议继承:

class A{
public:
   virtual bool Roots();
}
class Apples : public A
{}
class Beets : public A
{}

现在,Apples 和 Beets 都具有 Roots 功能,没有循环包含,并且它是公共的,因此它们可以相互访问(并且是唯一一个公共的,因此您很安全)。你甚至不需要知道根是红色还是蓝色。如果您稍后创建一个“Carrot”类,您的类也不需要更改以包含“OrangeRoots”。

【讨论】:

  • 谢谢,但我试图变得聪明,所以我让两个类相互关联。实际上,这两个类彼此无关,因此继承不起作用。一个类是 I/O 类,而另一个类保存 I/O 类的配置信息...
  • @Matt,问题仍然在于您的设计。如果类需要访问彼此的私有数据 - 它们彼此相关的。你想做的——不能直接做,我建议你间接做,但它仍然是一个尴尬的设计。如果您不想这样做 - 尝试重新考虑整个设计以使其正确。在正确的设计中,您不需要友元函数来访问其他类的私有数据成员。你在这里做错了。
  • 几乎从不适合配置类知道它在配置什么。 10 次中有 9 次是代码气味。
  • 您说得对,存在设计问题。 I/O 类是由其他人创建的,我正在使用配置类对其进行扩展。因为我不想编辑太多原始代码,所以我决定将一些 I/O 内容添加到配置类中。但我想那是错误的。我只需要咬紧牙关,将我转储到配置类中的类的 I/O 部分与 I/O 类合并。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多