Недавно я заметил странное поведение при использовании возвращенного пустого shared_ptr. Чтобы проиллюстрировать проблему, рассмотрим этот пример:
struct A {
A() { }
void foo() {
std::cout << "A::foo" << std::endl;
}
};
struct B {
B() :i(42) { }
void foo() {
std::cout << "B:foo with i: " << i << std::endl;
}
int i;
};
template<typename T>
std::shared_ptr<T> create_empty() {
return std::shared_ptr<T>();
}
Тогда звоню:
std::shared_ptr<A> pa(create_empty<A>());
pa->foo(); // #1: Works fine and prints: "A::foo".
std::shared_ptr<B> pb(create_empty<B>());
pb->foo(); // #2: Throws an exception.
Теперь мой вопрос: почему вызов # 1 работает (я ожидал также получить исключение) и если это правильное поведение, как запретить работу # 1. Я должен проверить, является ли возвращаемое значение пустым? Есть ли другие способы вернуть null или пустой shared_ptr? Я использую MSVC ++ 11, если это имеет значение …
Код в обоих случаях разыменовывает нулевой указатель. Поведение не определено, поэтому может случиться что угодно, включая вещи, которые, кажется, имеют смысл. Не пытайтесь осмыслить их. Не определено не определено.
Ни один из примеров действительно не работает, так как они используют нулевой указатель.
В первом случае вы действительно ничего не получаете от A, поэтому можете не заметить. Во втором случае доступ к i
члену крайне вероятно придется разыменовать this
указатель (и система заметит, что он нулевой).