简体   繁体   English

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

[英]Why can't my friend function access the private members?

The addBudget function in AuxiliaryOffice class is a friend function of the budget class. AuxiliaryOffice类中的addBudget函数是budget类的朋友函数。 But the compiler is giving me error, that it cannot access the private members of the Budget class. 但是编译器给我错误,它无法访问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;

The error you get is stopping your code from compile before friendship is even an issue. 您得到的错误是在友谊甚至没有成为问题之前就停止了代码的编译。

You declared Budget as an incomplete type: 您将预算声明为不完整的类型:

class Budget;

And then wrote code that calls functions on it, before the class is defined. 然后编写代码,以在定义类之前在其上调用函数。 That is not allowed. 那是不允许的。 You have to declare functions that use it, but NOT define it until after the class is defined. 您必须声明使用它的函数,但是直到定义了类之后才定义它。

That's why (one of the reasons why) we put class declarations in headers, and implementations in .cpp files. 这就是为什么(原因之一)我们将类声明放在标头中,并将实现放在.cpp文件中。 It also reduces coupling between files, and can help with build speeds. 它还可以减少文件之间的耦合,并有助于提高构建速度。

Here's a compacted version of your code that compiles, with most of the unessential lines removed (as you should aim to do in future questions): 这是编译后的代码的压缩版本,其中删除了大部分不必要的行(您应该在以后的问题中这样做):

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

see it live: https://godbolt.org/z/JYDZMz 现场观看: https//godbolt.org/z/JYDZMz

The problem is not about friendship, is about the order of definition. 问题不在于友谊,而在于定义的顺序。 At the point you've defined AuxiliaryOffice::addBudget the definition of Budget is incomplete, hence the member corpBudget isn't defined yet. 至此,您已经定义了AuxiliaryOffice::addBudgetBudget的定义不完整,因此尚未定义成员corpBudget

Change it to: 更改为:

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

That will work. 那可行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM