【问题标题】:Why can't my friend function access the private members?为什么我的好友功能无法访问私人会员?
【发布时间】:2019-01-08 02:33:15
【问题描述】:

AuxiliaryOffice 类中的 addBudget 函数是预算类的友元函数。但是编译器给了我错误,它不能访问 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;

【问题讨论】:

  • 一台计算机试图从头到尾编译你的程序。它从头到尾读取它,而不是相反。在您的计算机读取AuxiliaryOffice 并尝试编译它时,它根本不知道这个神秘的Budget 类是什么,它只是在那个时候前向声明的。这对您的编译器来说是一个很大的谜团,因此您的编译器对尝试访问未定义类的方法成员非常不满。

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


【解决方案1】:

你得到的错误是在友谊成为问题之前阻止你的代码编译。

您将 Budget 声明为不完整类型:

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

【讨论】:

    【解决方案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;
    }
    

    这会起作用的。

    【讨论】:

    • 如果AuxiliaryOffice::addBudget 的定义在头文件中,您需要声明它inline
    • 你有点过火了,inline 只需要在定义而不是声明中。
    猜你喜欢
    • 2021-11-15
    • 2021-01-02
    • 1970-01-01
    • 1970-01-01
    • 2021-08-05
    • 1970-01-01
    相关资源
    最近更新 更多