为什么不能在一个朋友类中实例化其构造函数是私有的类?

Syf*_*u_H 18 c++ constructor friend-class

我有两节课;Salary旨在保存有关雇员薪水的信息和计算,并且Employee具有类型对象class Salary和一些成员,例如雇员的姓名和地址...

  • 我想做的是防止class Salary被实例化,除了 class Employee。所以我宣布了Salary私有的建设者,并成为Employee的朋友Salary。但是我得到了错误:

    class Employee;
    
    class Salary {
        public:
    
        private:
            Salary() : revenue_{}, cost_{} {}
            Salary(int x, int y) : revenue_{ x },
            cost_{ y } {
    
            }
            int revenue_, cost_;
            friend class Employee;
    };
    
    class Employee {
        public:
            std::string name_;
            Salary sal;
    };
    
    int main(){
    
        Employee emp{}; // "Salary::Salary()" is inaccessible
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 如果我向前声明,问题就解决了main

    int main(int, char*[]);
    
    Run Code Online (Sandbox Code Playgroud)

    并在Salary中结交main类似的朋友class Salary

    class Salary {
        //...
        friend int main(int argc, char* argv[]);
    };
    
    Run Code Online (Sandbox Code Playgroud)

现在程序可以正确编译了!

***如果以这种方式声明对象,则main中的另一件事:

Employee emp; // ok
Employee emp{}; // error?
Run Code Online (Sandbox Code Playgroud)

zda*_*dan 18

由于您没有为Employee括号提供构造函数,因此初始化时Employee emp{};将执行聚合初始化,这实际上意味着在的上下文中,每个成员都使用默认规则进行了一对一的初始化main()。由于main()无法访问Salary构造函数,因此失败。

正如其他人指出的那样,添加Employee默认构造函数将解决您的问题:

class Employee {
    public:
        Employee() = default;
        std::string name_;
        Salary sal;
};
Run Code Online (Sandbox Code Playgroud)