2017-04-18 24 views
0

假設我有一個具有兩種方法的類。其中一個應該在容器中找到一個對象並按值返回,另一個應該通過引用返回。當然,我希望第一種方法是constthisconst),第二種方法不是。編寫兩種返回C++中相同項目的值和引用的方法的最佳方法

有沒有一種方法來重新使用這兩種方法之間的代碼,而不引入他們都依賴的第三種方法?下面我給出了這個問題的一個玩具例子,其中人們應該想象find步驟實際上要複雜得多。

在「可能的實現1」下面,有一個錯誤,由於這樣的事實,我打電話(非constget_ref從內(constget_value。在「可能的實現2」中,引用是從值的臨時副本創建的,這當然是一個主要問題。

在需要const引用的情況下,當然沒有問題,但假設我實際上需要一個普通引用。

// Header: 

#include <string> 
#include <map> 
using std::string; 
using std::map; 

class Test { 
    public: 
     map< string, string > stuff; 
     string & get_ref(const string key); 
     string get_value(const string key) const; 
}; 


// Possible implementation 1: 

string Test::get_value(const string key) const { 
    return get_ref(key); 
} 

string & Test::get_ref(const string key) { 
    return stuff.find(key)->second; 
} 


// Possible implementation 2 (obviously wrong, but here for the sake of pointing that out): 

string Test::get_value(const string key) const { 
    return stuff.find(key)->second; 
} 

string & Test::get_ref(const string key) { 
    return get_value(key); 
} 
+0

想一想在第二次執行中get_ref正在返回什麼。如果你試圖實際編譯*編譯器告訴你什麼? –

+0

在一個不相關的說明中,你還應該考慮如果找不到密鑰並且'find'函數返回'end'迭代器會發生什麼情況。 –

+0

@Someprogrammerdude如果你暗指暫時返回,OP已經提到,作爲不使用第二次執行的原因 –

回答

0

直接回答這個問題,避免使用第三/私有方法的唯一方法是投const -ness的this了。

使用「可能實現1」,修改如下:

string Test::get_value(const string key) const { 
    return const_cast<Test*>(this)->get_ref(key); 
} 

現在,看看其他兩個問題有點更廣泛的:首先,你應該改變get_ref()它確實是這樣,如果stuff.find(key)回報end()一些明智的(一個過去末端的迭代器)。選項包括拋出異常或返回空字符串。

其次,簡單的效率改進是指出方法參數按值傳遞字符串,可以輕鬆安全地更改以通過const string& key

+0

我想我是在@someprogrammerdude同時輸入上面的內容:-S –

+0

謝謝,我想我會用const_cast去。我上面評論說,我明白應該有錯誤處理。我只是想盡可能簡短地舉例(每個函數中有一行)。至於通過值或引用傳遞的相對速度,我的理解是,對於小型內置類型,這更依賴於編譯器而不是任何東西 - 但這是我所知甚少的。 – sasquires

+0

除了我自己的回答外,我還應該指出,在返回空字符串或類似字符時要小心。 'return「」;'是不安全的(返回對本地/臨時對象的引用)。最好聲明一個靜態成員或靜態局部變量並返回它。 –

相關問題