![](/img/trans.png)
[英]What should happen when the return value from a C++ function that returns a reference of an undefined object type is not assigned?
[英]What type of object should this function return?
考慮這個課程:
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>
。 如果調用者將其轉換為shared_ptr
我認為這與#2具有相同的感知問題。 我投票支持:
boost::optional<Widget&> widget() {
static Widget w; // no reason for this to be a pointer
static bool initialized = false;
if (!initialized) {
if (!w.initialize()) {
return boost::none;
}
initialized = true;
}
return w;
}
它清楚地表明調用者沒有以任何方式擁有Widget
,不必擔心調用者delete
Widget
,並且可以清楚調用是否成功。
在這里做正確的事情不是原始指針嗎? 它已經表達了限制。 它可能會失敗(通過返回nullptr),並且由於它沒有對指針做出任何承諾,因此調用者無法安全地將其刪除。 你得到一個原始指針,你不能假設你被允許做出有關指向對象生命周期的任何陳述。
Herb Sutter在這種情況下的推薦(第4項http://herbsutter.com/2013/05/30/gotw-90-solution-factories/ )是返回optional
。
函數可能返回指針可能還有一個原因,即返回nullptr以指示無法生成對象。 通常,如果我們無法加載窗口小部件,最好拋出異常來報告錯誤。 但是,如果無法加載窗口小部件是正常操作並且不應該被視為錯誤,則返回一個可選項,並且如果不需要報告其他類型的錯誤,則可能使工廠無法通過返回空的可選項進行良好通信。
正如其他人所指出的,如果工廠只生產一件產品,那么工廠也許不是正確的術語。 這似乎是一個單身人士。
考慮到:
我會嘗試這樣的事情:
class Widget {
public:
static Widget& Instance() {
static Widget w{};
return w;
}
private:
Widget() {
// Expensive construction
}
Widget(const Widget&) = delete; // avoid copy
};
為了使生命周期和所有權更清晰,我將使用Singleton模式的約定,並使您的函數成為Widget
類上的靜態getInstance
函數。
class Widget {
bool initialize();
public:
static Widget* getInstance() {
static Widget w;
static bool initialized = false;
if (!initialized) {
if (!w.initialize()) {
return nullptr;
}
initialized = true;
}
return &w;
}
};
我認為原始指針返回類型記錄了調用者不應該獲得所有權的事實,它可能為null。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.