#cpp
Привет. Вроде бы проблема проста, но я с ней никогда не сталкивался и простым поиском с ходу не нашёл, поэтому решил не терять сил и времени и задать вопрос. Пример: #includestruct A { protected: A() {} friend class B; }; struct B { std::unique_ptr a; B() : a( std::make_unique() ) {} }; int main() { B b; } Этот пример не скомпилируется. Но если убрать protected или заменить std::unique_ptr на обычный указатель, то всё будет нормально. Я же не хочу избавляться ни от того, ни от другого. Как быть?
Ответы
Ответ 1
Еще можно так. Собственно, о чем и был мой второй комментарий два часа назад. #includestruct A { protected: A() {} friend struct B; friend std::unique_ptr std::make_unique(); }; struct B { std::unique_ptr a; B() : a( std::make_unique() ) {} }; int main() { B b; } Прув: https://ideone.com/uesddg УПД: с этим вариантом мы по прежнему создаем экземпляр при помощи make_unique, но при этом не даем "не друзьям" доступ до создания экземпляра. #include struct A { protected: A() {} friend struct B; static std::unique_ptr Create() { return std::make_unique(); } }; struct B { std::unique_ptr a; B() : a( A::Create() ) {} }; int main() { B b; } Ответ 2
Функция std::make_unique не является дружественной функцией для класса A. Поэтому она не может создавать объекты класса A Но вы можете написать B() : a( new A() ) {} Вот простая демонстрационная программа #includeint main() { struct A { protected: A() {} friend struct B; }; struct B { std::unique_ptr a; B() : a( new A() ) {} }; B b; }
Комментариев нет:
Отправить комментарий