2016-01-02 48 views
0

這是一個相當普遍的API設計問題,而不是C++相關的問題,無論如何,那些預期會返回一個類的實例的函數通常會被接受:返回NULL出錯或返回該類沒有數據的實例?返回NULL與返回一個沒有數據的obj

這是我的實際代碼:https://github.com/alexandernst/cpp-bitstring/blob/76030321b3a424236c3380067a0dc4f132fb8369/src/Bits.cpp#L360

+0

回到當天返回NULL是首選,因爲它避免了必須複製大對象。但是,現在使用C++ 11和RVO的時候,再也沒有這個意義了,所以我會說返回一個空實例/拋出一個異常。此外,使用裸體'新'通常是一個壞主意,特別是如果你有智能指針訪問。 –

回答

1

一般來說我會返回NULL或拋出。代碼失敗需要儘早理解。

返回「破碎」對象的替代方法要求每個函數都理解對象已損壞並處理它。

的NULL /扔要求您辦理各項建設的錯誤,並在你的臉上,如果失敗

+0

如果函數返回一個類的實例,則不能「返回NULL」。 –

1

問自己這個問題:

「什麼是我的函數的承諾,因此,其客戶的期望

如果函數承諾返回一個對象,拋出一個異常,如果它不能例外表示無法遵守諾言

例如:。

T make_t(Arg arg); // promises to make a T, should throw if it can't 

如果該功能的承諾,它可能返回一個對象,然後表示,在接口:

boost::optional<T> maybe_make_t(Arg arg); 

在這種情況下,我們不希望一個異常,如果該對象不言,只是一個空的optional<T>。因爲我們已經返回了一個可選項,所以調用者必須在使用該值之前檢查它(或遭受異常)。他現在受到保護,免受他自己的邏輯錯誤。

如果你可以避免它,試着避免總是返回指針。他們爲您的呼叫者創造了令人頭痛的問題。

也許(出於某種原因)您想要避免例外,但仍然安全地報告失敗以履行承諾?

這裏有一種方法:

boost::variant<T, std::string> make_t_or_reason_why_not(Arg arg); 

現在你強迫呼叫者使用靜態遊客來處理你的結果(這是好的這迫使他覆蓋所有代碼路徑!)。

的承諾是,你會的東西,而且它會要麼Tstring解釋爲什麼T並未執行。