2016-03-28 90 views
0

我有一個返回類型爲std::string&的函數,如果函數中沒有條件匹配,如何返回NULL string&C++函數返回NULL字符串參考

std::string& SomeClass::getSomething() 
{ 
    if(){...} 
    else if(){...} 
    // return a NULL 
} 
+9

你不能。沒有這樣的東西,作爲NULL'std :: string'。你需要重新思考你的方法。 – juanchopanza

+0

也許會返回一個空字符串? – DimChtz

+0

你可以返回一個指針來代替引用,然後你可以返回一個NULL指針。 – Unimportant

回答

5

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 ""; 
    } 
} 
+0

鑑於在原始代碼中,返回者擁有被引用的字符串,我認爲可以返回非擁有的原始指針。返回unique_ptr將所有權轉移給調用者,這是語義WRT中的一個嚴重變化。原始代碼。 – juanchopanza

+0

@juanchopanza注意。 –

0

正如評論由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 
} 
+0

不要使用新的,但'stringPtr = make_shared ...' –

+0

爲什麼shared_ptr?這裏唯一的參與者似乎是來電者和getSomething,並且getSometing在轉交給呼叫者時不在場。 – user4581301

+0

@DieterLücking指出。之前無法修復,我用SO做了「Ooops東西出錯了」,很奇怪。 – Nacho

1

無論如何,你不會返回NULL,但nullptr。 此外,你應該小心從函數返回引用,並確保引用referes到一個有效的,活的對象。返回對本地對象的引用是錯誤的。

你不能返回nullptr因爲nullptr是一個指針而且string&是一個引用 - 不同的類型。

你的選擇是:

  1. 拋出一個異常
  2. 使用類似選修課程(boost::optional等。)

個人,如果我知道有一個很大的可能性的功能可能會失敗,我將結果傳遞引用類型的參數和返回bool來表示失敗

bool SomeClass::getSomething(std::string& result) 
{ 
    if(){result = "success 1"; return true; } 
    else if(){result = "success 2"; return true; } 
    return false. 
} 
+1

70年代叫...! –

+0

@BarryTheHatchet所以當.Net給你'TryParse','TryGetValue'這很酷且現代,但在C++上它突然古老而醜陋? –

+1

我什麼時候說'TryParse'和'TryGetValue'是「很酷且現代的」? (提示:我沒有)(另一個提示:那些古老而又醜陋) –

0

返回空的成功字符串''可能在這裏有意義。

從你的代碼片段中,我會想知道你是否在類的封面下窺視,做出類本身應該做出的決定。請參閱Martin Fowler關於「Tell, don't Ask」的文章,該文章也提及The Pragmatic Programmers的原創文章。