我有两节课; 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?
答案 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)。