I have two classes; Salary
that is intended to hold information and calculations regarding the salary of an employee and Employee
that has an object of type class Salary
and some members like name and address of the employee...
What I want to do is to prevent class Salary
from being instantiated except by class Employee
. So I declared the constructors of Salary
private and made Employee
a friend of Salary
. But I get errors:
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
}
The problem goes away if I forward declare main
:
int main(int, char*[]);
And make main
a friend of class Salary
like so in Salary:
class Salary {
//...
friend int main(int argc, char* argv[]);
};
Now the program compiles correctly!
*** Another thing in main if I declare an object this way:
Employee emp; // ok
Employee emp{}; // error?
Because you don't provide a constructor for Employee
the braces in your initialization Employee emp{};
will perform an aggregate initialization, which essentially means that each member is initialized one-by-one using the default rules, in the context of main()
. Since main()
doesn't have access to the Salary
constructor, it fails.
As others have pointed out, adding an Employee
default constructor will resolve your problem:
class Employee {
public:
Employee() = default;
std::string name_;
Salary sal;
};