私には2つのクラスがあります。 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[]);
};
これでプログラムは正しくコンパイルされます!
***この方法でオブジェクトを宣言した場合のメインのもう1つのこと:
Employee emp; // ok
Employee emp{}; // error?
Employee
のコンストラクターを提供していないため、初期化で中かっこ_Employee emp{};
_は 集計初期化 を実行します。これは基本的に、各メンバーが1つずつ初期化されることを意味しますmain()
のコンテキストで、デフォルトのルールを使用するもの。 main()
はSalary
コンストラクタにアクセスできないため、失敗します。
他の人が指摘したように、Employee
デフォルトコンストラクターを追加すると問題が解決します。
_class Employee {
public:
Employee() = default;
std::string name_;
Salary sal;
};
_
クラスEmployee
のデフォルトコンストラクターを明示的に宣言する必要があるため、uniform initialization
を介してオブジェクトを初期化できます。
class Employee {
public:
Employee(){} // add it
std::string name_;
Salary sal;
};
int main(){
Employee emp{}; // now this should compile
}
Employee
のctorを呼び出すには、Salary
のctorが必要です。 Salary
のctorはmain
からアクセスできません。
例えば:
class Employee {
public:
Employee() : sal() {}
public:
std::string name_;
Salary sal;
};
Main()関数で "Employee emp"の後にある "{}"を消去すると、正常にコンパイルされます(Fedora 27のgcc 7.3.1)。