0
考虑下面的代码片段:共享指针初始化列表构造和改变它的类型构造
#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:我不知道,问问你的编译器(即看看机器代码)!辩论未定义行为的细节通常没有什么价值。任何事情都可能发生,你看到的任何“任何东西”的味道基本上是不相关的。如果按下,我会说因为原始的部件是trival和空的,所以不需要生成任何代码来初始化它(所有类型的值都是相等的),所以缺少一个值就没有被注意到。 –
是的,如果您也输出共享指针的使用计数为零,这并不奇怪。我希望它会在两种情况下都会出现故障。感谢您的回答。 –