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和空的,所以不需要生成任何代碼來初始化它(所有類型的值都是相等的),所以缺少一個值就沒有被注意到。 –
是的,如果您也輸出共享指針的使用計數爲零,這並不奇怪。我希望它會在兩種情況下都會出現故障。感謝您的回答。 –