我有一個返回類型爲std::string&
的函數,如果函數中沒有條件匹配,如何返回NULL string&
?C++函數返回NULL字符串參考
std::string& SomeClass::getSomething()
{
if(){...}
else if(){...}
// return a NULL
}
我有一個返回類型爲std::string&
的函數,如果函數中沒有條件匹配,如何返回NULL string&
?C++函數返回NULL字符串參考
std::string& SomeClass::getSomething()
{
if(){...}
else if(){...}
// return a NULL
}
C++引用不能爲空。如果你正在返回一個對象的引用,這個對象的生存期與函數調用的範圍沒有關係,比如數據成員,你可以安全地返回一個原始指針(我會推薦一個指向const的指針)。
std::string const* foo::bar() const {
if (condition) {
return &some_data_member;
} else {
return nullptr;
}
}
如果不是,最佳解決方案是(在C++ 17或std::optional
)使用包裝類型等boost::optional
。這不僅可以讓你通過值返回一個可選對象(這可能會更高性能),但它也是self-documenting。
std::optional<std::string> foo::bar() const {
if (condition) {
return "hello, world";
} else {
return std::nullopt;
}
}
或者,您可以返回一個指針,該指針可以爲null。但是,返回一個原始指針引發了誰負責刪除動態分配的字符串的問題。在這種情況下,返回std::unique_ptr
將是最好的選擇,因爲所有權顯式傳遞給調用者。
std::unique_ptr<std::string> foo::bar() const {
if (condition) {
return std::make_unique<std::string>("hello, world");
} else {
return nullptr;
}
}
或者甚至更簡單,你可以返回一個空字符串,如果這可能在你的情況。說實話,這是我的首選方法(KISS)。
std::string foo::bar() const {
if (condition) {
return "hello, world";
} else {
return "";
}
}
鑑於在原始代碼中,返回者擁有被引用的字符串,我認爲可以返回非擁有的原始指針。返回unique_ptr將所有權轉移給調用者,這是語義WRT中的一個嚴重變化。原始代碼。 – juanchopanza
@juanchopanza注意。 –
正如評論由juanchopanza說,你不能。
如果您需要測試NULL
,您可以使用智能指針重新考慮您的方法。例如,一個std::shared_ptr<std::string>
:
std::shared_ptr<std::string> SomeClass::getSomething()
{
std::shared_ptr<std::string> stringPtr;
if(){
//...
stringPtr = std::make_shared<std::string>("Whatever string goes here");
}
else if(){
//...
stringPtr = std::make_shared<std::string>("The other string...");
}
return stringPtr;
}
然後,你可以只與它的隱式轉換測試std::shared_ptr
到布爾:
auto strReturnedPtr = someClassObj.getSomething();
if (strReturnedPtr)
{
// Do stuff
}
不要使用新的,但'stringPtr = make_shared ...' –
爲什麼shared_ptr?這裏唯一的參與者似乎是來電者和getSomething,並且getSometing在轉交給呼叫者時不在場。 – user4581301
@DieterLücking指出。之前無法修復,我用SO做了「Ooops東西出錯了」,很奇怪。 – Nacho
無論如何,你不會返回NULL
,但nullptr
。 此外,你應該小心從函數返回引用,並確保引用referes到一個有效的,活的對象。返回對本地對象的引用是錯誤的。
你不能返回nullptr
因爲nullptr
是一個指針而且string&
是一個引用 - 不同的類型。
你的選擇是:
boost::optional
等。)個人,如果我知道有一個很大的可能性的功能可能會失敗,我將結果傳遞引用類型的參數和返回bool
來表示失敗
bool SomeClass::getSomething(std::string& result)
{
if(){result = "success 1"; return true; }
else if(){result = "success 2"; return true; }
return false.
}
70年代叫...! –
@BarryTheHatchet所以當.Net給你'TryParse','TryGetValue'這很酷且現代,但在C++上它突然古老而醜陋? –
我什麼時候說'TryParse'和'TryGetValue'是「很酷且現代的」? (提示:我沒有)(另一個提示:那些古老而又醜陋) –
返回空的成功字符串''可能在這裏有意義。
從你的代碼片段中,我會想知道你是否在類的封面下窺視,做出類本身應該做出的決定。請參閱Martin Fowler關於「Tell, don't Ask」的文章,該文章也提及The Pragmatic Programmers的原創文章。
你不能。沒有這樣的東西,作爲NULL'std :: string'。你需要重新思考你的方法。 – juanchopanza
也許會返回一個空字符串? – DimChtz
你可以返回一個指針來代替引用,然後你可以返回一個NULL指針。 – Unimportant