15

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

  • 我想要做的是防止class Salary被实例化,除了 class Employee. 所以我声明了Salaryprivate 的构造函数并结交EmployeeSalary. 但我得到错误:

    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*[]);
    

    并在薪水中结交main这样的朋友:class Salary

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

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

*** 如果我以这种方式声明一个对象,主要的另一件事是:

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

4 回答 4

18

因为您没有为Employee初始化中的大括号提供构造函数,所以Employee emp{};将执行聚合初始化,这本质上意味着每个成员都使用默认规则在main(). 由于main()无权访问Salary构造函数,因此失败。

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

class Employee {
    public:
        Employee() = default;
        std::string name_;
        Salary sal;
};
于 2019-04-23T22:15:58.203 回答
4

您需要Employee的 ctor 来调用 的 ctor Salary。的 ctorSalary无法从main.

例如:

class Employee {
public:
    Employee() : sal() {}
    public:
        std::string name_;
        Salary sal;
};
于 2019-04-23T22:04:06.613 回答
1

您必须显式声明类的默认构造函数,Employee因此您可以通过以下方式初始化 abject uniform initialization

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

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

}
于 2019-04-23T22:14:02.990 回答
1

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

于 2019-04-23T22:03:40.153 回答