为什么我不能在朋友 class 中实例化一个其构造函数为私有的 class?
Why can I not instantiate a class whose constructor is private in a 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
}
如果我转发声明main
,问题就会消失:
int main(int, char*[]);
并让 main
成为 class Salary
的朋友,就像在工资中这样:
class Salary {
//...
friend int main(int argc, char* argv[]);
};
现在程序编译正确!
*** 如果我这样声明一个对象,主要的另一件事是:
Employee emp; // ok
Employee emp{}; // error?
如果您在 main() 函数中删除 "Employee emp" 之后的“{}”,它就可以正常编译(Fedora 27 上的 gcc 7.3.1)。
您需要 Employee
的 ctor 才能调用 Salary
的 ctor。无法从 main
访问 Salary
的构造函数。
例如:
class Employee {
public:
Employee() : sal() {}
public:
std::string name_;
Salary sal;
};
您必须显式声明 class Employee
的默认构造函数,因此您可以通过 uniform initialization
:
初始化对象
class Employee {
public:
Employee(){} // add it
std::string name_;
Salary sal;
};
int main(){
Employee emp{}; // now this should compile
}
因为您没有为 Employee
提供构造函数,所以初始化 Employee emp{};
中的大括号将执行 aggregate initialization,这实际上意味着每个成员都被逐一初始化一种使用默认规则,在 main()
的上下文中。由于 main()
无法访问 Salary
构造函数,因此失败。
正如其他人所指出的,添加一个 Employee
默认构造函数将解决您的问题:
class Employee {
public:
Employee() = default;
std::string name_;
Salary sal;
};
我有两个类; 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 }
如果我转发声明
main
,问题就会消失:int main(int, char*[]);
并让
main
成为class Salary
的朋友,就像在工资中这样:class Salary { //... friend int main(int argc, char* argv[]); };
现在程序编译正确!
*** 如果我这样声明一个对象,主要的另一件事是:
Employee emp; // ok
Employee emp{}; // error?
如果您在 main() 函数中删除 "Employee emp" 之后的“{}”,它就可以正常编译(Fedora 27 上的 gcc 7.3.1)。
您需要 Employee
的 ctor 才能调用 Salary
的 ctor。无法从 main
访问 Salary
的构造函数。
例如:
class Employee {
public:
Employee() : sal() {}
public:
std::string name_;
Salary sal;
};
您必须显式声明 class Employee
的默认构造函数,因此您可以通过 uniform initialization
:
class Employee {
public:
Employee(){} // add it
std::string name_;
Salary sal;
};
int main(){
Employee emp{}; // now this should compile
}
因为您没有为 Employee
提供构造函数,所以初始化 Employee emp{};
中的大括号将执行 aggregate initialization,这实际上意味着每个成员都被逐一初始化一种使用默认规则,在 main()
的上下文中。由于 main()
无法访问 Salary
构造函数,因此失败。
正如其他人所指出的,添加一个 Employee
默认构造函数将解决您的问题:
class Employee {
public:
Employee() = default;
std::string name_;
Salary sal;
};