Почему функция моего друга не может получить доступ к частным пользователям? - PullRequest
0 голосов
/ 08 января 2019

Функция addBudget в классе AuxiliaryOffice является функцией-другом бюджетного класса. Но компилятор выдает ошибку, что он не может получить доступ к закрытым членам класса Budget.

class Budget;
class AuxiliaryOffice
{
private:
    double auxBudget;
public:
    AuxiliaryOffice()
    {
        auxBudget = 0;
    }
    double getDivisionBudget()
    {
        return auxBudget;
    }
    void addBudget(double a, Budget &ref)
    {
        ref.corpBudget += a;
        auxBudget += a;
    }
};
class Budget
{
private:
    static double corpBudget;
    double divisionBudget;
    friend void AuxiliaryOffice::addBudget(double, Budget&);
public:
    Budget()
    {
        divisionBudget = 0;
    }
    void addBudget(double a)
    {
        corpBudget += a;
        divisionBudget += a;
    }
    double getDivisionBudget() const
    {
        return divisionBudget;
    }
    double getCorpBudget() const
    {
        return corpBudget;
    }
};
double Budget::corpBudget = 0;

Ответы [ 2 ]

0 голосов
/ 08 января 2019

Ошибка, которую вы получаете, останавливает ваш код от компиляции до того, как дружба станет проблемой.

Вы объявили бюджет как неполный тип:

class Budget;

А затем написал код, который вызывает функции перед тем, как класс будет определен. Это не разрешено. Вы должны объявить функции, которые его используют, но НЕ определять его до тех пор, пока класс не будет определен.

Вот почему (одна из причин) мы помещаем объявления классов в заголовки, а реализации в файлы .cpp. Это также уменьшает связь между файлами и может помочь в увеличении скорости сборки.

Вот сжатая версия вашего кода, которая компилируется, с удалением большинства необязательных строк (как вы должны попытаться сделать в будущих вопросах):

class Budget;
class AuxiliaryOffice {
    double auxBudget = 0;

public:
    void addBudget(double a, Budget &ref);
};

class Budget {
    // Unrelated, but useful to know:
    // inline statics can be initialized in the class like this, no
    // definition necessary in the .cpp file.
    inline static double corpBudget = 0; 
    friend void AuxiliaryOffice::addBudget(double, Budget&);
};

// if in .cpp, remove "inline", if in header, keep it
inline void AuxiliaryOffice::addBudget(double a, Budget &ref) {
    ref.corpBudget += a;
}

посмотреть вживую: https://godbolt.org/z/JYDZMz

0 голосов
/ 08 января 2019

Проблема не в дружбе, а в порядке определения. В момент, когда вы определили AuxiliaryOffice::addBudget, определение Budget является неполным, следовательно, член corpBudget еще не определен.

Измените его на:

class Budget;
class AuxiliaryOffice
{
private:
    double auxBudget;
public:
    AuxiliaryOffice()
    {
    auxBudget = 0;
    }
    double getDivisionBudget()
    {
    return auxBudget;
    }
    void addBudget(double a, Budget &ref);
};


class Budget
{
private:
    static double corpBudget;
    double divisionBudget;
    friend void AuxiliaryOffice::addBudget(double, Budget&);
public:
    Budget()
    {
        divisionBudget = 0;
    }
    void addBudget(double a)
    {
        corpBudget += a;
        divisionBudget += a;
    }
    double getDivisionBudget() const
    {
        return divisionBudget;
    }
    double getCorpBudget() const
    {
        return corpBudget;
    }
};
double Budget::corpBudget = 0;

inline void AuxiliaryOffice::addBudget(double a, Budget &ref)
{
    ref.corpBudget += a;
    auxBudget += a;
}

Это сработает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...