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

时间:2019-04-23 21:56:40

标签: c++ constructor friend-class

我有两节课; Salary用于保存有关员工薪水的信息和计算,Employee用于保存对象类型为class Salary的对象,某些对象如员工的姓名和地址... / p>

  • 我想做的是防止除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
    }
    
  • 如果我向前声明main,问题就消失了:

    int main(int, char*[]);
    

    在Salary中像这样使main成为class Salary的朋友:

    class Salary {
        //...
        friend int main(int argc, char* argv[]);
    };
    

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

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

Employee emp; // ok
Employee emp{}; // error?

4 个答案:

答案 0 :(得分:18)

因为您没有为Employee提供构造函数,所以初始化Employee emp{};会执行aggregate initialization,这实际上意味着每个成员都使用来逐个初始化main()上下文中的默认规则。由于main()无权访问Salary构造函数,因此失败。

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

class Employee {
    public:
        Employee() = default;
        std::string name_;
        Salary sal;
};

答案 1 :(得分:3)

您需要Employee的ctor才能调用Salary的ctor。无法从Salary访问main的ctor。

例如:

class Employee {
public:
    Employee() : sal() {}
    public:
        std::string name_;
        Salary sal;
};

答案 2 :(得分:3)

您必须显式声明类Employee的默认构造函数,以便可以通过uniform initialization来初始化abject:

class Employee {
    public:
        Employee(){} // add it
        std::string name_;
        Salary sal;
};

int main(){
    Employee emp{}; // now this should compile

}

答案 3 :(得分:1)

如果在main()函数中删除“ Employee emp”之后的“ {}”,则编译就很好(Fedora 27上的gcc 7.3.1)。