Взаимные функции друга-члена = циркулярные объявления включения - PullRequest
1 голос
/ 31 мая 2011

У меня есть два класса, определенных в разных файлах 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 стал другом для Apple таким способом, которым было бы достаточно предварительного объявления класса, но я бы хотелдостаточно разрешить только одну функцию частному доступу.

Есть предложения?Заранее спасибо, Мэтт.

(PS, почему возврат каретки между каждым из "Спасибо заранее", "Мэтт" не приводит к переводу строки?)

Ответы [ 2 ]

2 голосов
/ 31 мая 2011

Вы можете использовать функции-друзья, которые вызывают функции-члены.

//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);
0 голосов
/ 31 мая 2011

Похоже, у вас есть проблемы с дизайном. Я бы предложил наследование:

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

Теперь и у яблок, и у свеклы есть функция Roots, без циклических включений, и она общедоступна, поэтому они могут обращаться друг к другу (и только к общедоступной, так что вы в безопасности). Вам даже не нужно знать, красные ли корни или синие. И если позже вы создадите класс «Carrot», ваши классы не должны будут меняться, чтобы включить «OrangeRoots».

...