Почему я не могу создать экземпляр класса, конструктор которого является закрытым в другом классе?
У меня есть два класса; 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?
Ответы
Ответ 1
Поскольку вы не предоставляете конструктор для скобок Employee
при инициализации Employee emp{};
выполнит агрегатную инициализацию, что по сути означает, что каждый элемент инициализируется один за другим с использованием правил по умолчанию в контексте main()
. Поскольку main()
не имеет доступа к конструктору Salary
, происходит сбой.
Как уже отмечали другие, добавление конструктора Employee
умолчанию решит вашу проблему:
class Employee {
public:
Employee() = default;
std::string name_;
Salary sal;
};
Ответ 2
Вам нужен Employee
Ctor, чтобы вызвать Ctor Salary
. Ctor of Salary
не доступен с main
.
например:
class Employee {
public:
Employee() : sal() {}
public:
std::string name_;
Salary sal;
};
Ответ 3
Вы должны явно объявить конструктор по умолчанию класса Employee
таким образом, вы можете инициализировать объект с помощью uniform initialization
:
class Employee {
public:
Employee(){} // add it
std::string name_;
Salary sal;
};
int main(){
Employee emp{}; // now this should compile
}
Ответ 4
Если вы удалите "{}" после "Employee emp" в своей функции main(), она будет прекрасно скомпилирована (gcc 7.3.1 в Fedora 27).