为什么我的朋友功能无法访问私人成员?

时间:2019-01-08 02:33:16

标签: c++ c++11 visual-c++

AuxiliaryOffice类中的addBudget函数是budget类的朋友函数。但是编译器给我错误,它无法访问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 :(得分:3)

您遇到的错误是在友谊甚至没有成为问题之前就停止了代码的编译。

您将预算声明为不完整的类型:

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

答案 1 :(得分:2)

问题不在于友谊,而在于定义的顺序。在您定义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;
}

那行得通。