Рассмотрим следующий фрагмент кода:Общий указатель Список инициализатор конструктора и изменения его типа конструктор
#include <memory>
#include <typeinfo>
#include <iostream>
class Widget {
};
int main() {
auto shared_ptr_to_widget = std::shared_ptr<Widget>({});
std::cout << "type of shared_ptr_to_widget: " << typeid(shared_ptr_to_widget).name() << std::endl;
auto maybe_a_widget = *shared_ptr_to_widget;
std::cout << "type of maybe_a_widget: " << typeid(maybe_a_widget).name() << std::endl;
}
Этот выход будет:
> type of shared_ptr_to_widget: St10shared_ptrI6WidgetE
> type of maybe_a_widget: 6Widget
Однако, если я заменю класс Widget с:
class Widget {
public:
Widget(): a{1}{}
int a;
};
Затем он неисправен на следующей линии:
auto maybe_a_widget = *shared_ptr_to_widget;
Я понимаю, если я на самом деле хотел сделать общий указатель на экземпляр объекта следует использовать
std::make_shared<Widget>()
и это будет на самом деле вызвать конструктор виджета, и все будет хорошо и денди. Но я бы очень хотел понять, что здесь происходит, и почему поведение изменяется на основе конструктора класса Widget.
Я попытался взглянуть на конструкторы для shared_ptr http://en.cppreference.com/w/cpp/memory/shared_ptr/shared_ptr, но я немного потерялся. Я полагаю, что это отсутствие понимания того, что на самом деле происходит при использовании пустого списка инициализаторов в качестве параметра для shared_ptr <>().
Как компилятор делает это мимо этой стадии в первой реализации Widget? Он должен быть нулевым указателем на класс типа Widget в обоих сценариях? –
@BrockHargreaves: Я не знаю, спросите своего компилятора (например, посмотрите на машинный код)! В общем, очень мало смысла обсуждать детали неопределенного поведения. Все может случиться, и какой вкус «ничего», который вы видите, в основном не имеет значения. Если нажать, я бы сказал, что, поскольку исходный виджет треугольный и пустой, для его инициализации не нужно генерировать код (все значения этого типа равны), и поэтому отсутствие значения оставалось незамеченным. –
Да, неудивительно, что если вы также выведите количество использования общего указателя, оно равно нулю. Однако я хотел бы, чтобы это произошло в обоих сценариях. Спасибо за Ваш ответ. –