Рассмотрим этот класс:Какой тип объекта должен возвращать эта функция?
class Widget
{
Widget::Widget();
bool initialize();
}
Widget
имеет следующие характеристики:
initialize()
должен быть вызван, чтобы полностью построитьinitialize()
может неinitialize()
дорого
Учитывая, что я герметизирующего создание в функции фабрики, которая всегда возвращает тот же экземпляр Widget
:
Widget* widget() {
static auto w = new Widget;
static auto initialized = false;
if (!initialized) {
if (!w->initialize()) {
return nullptr;
}
initialized = true;
}
return w;
}
Что следует возвращаемый тип widget()
быть?
В частности, я хотел бы как-то пояснить, что срок службы возвращаемого Widget
пережитит любого вызывающего абонента, но без ссылки на внутреннюю реализацию.
- Возвращает необработанный указатель и добавляет комментарий, который гласит: «Возвращаемый указатель указывает на объект со статическим временем хранения, который не будет удален до конца программы». Это просто, но не самодокументируемо.
- Возврат
std::shared_ptr<Widget>
. Это самодокументируется, но мне не нравится, что он внесет совершенно ненужные накладные расходы на подсчет ссылок. - Возврат
std::unique_ptr<Widget>
с пользовательской функцией удаления, которая не работает. Я думаю, что такая же проблема воспринимается как # 2, если вызывающий преобразует ее вshared_ptr
.
Это действительно вопрос мнения, но в данном конкретном случае я не стал бы беспокоиться о пересчете накладных расходов. Если ваш тип виджета «дорог», чтобы создать, то любые «ненужные затраты на подсчет ссылок», вероятно, будут тривиальными по сравнению. – MrEricSir
Язык C++ не поощряет использование интерфейсов. Но да, они - полная лаваша, чтобы отлаживать, разоблачать реализацию сложно. –
Должны ли мы игнорировать многопоточность? (Даже в C++ 11 это небезопасно) –