2013-11-15 90 views
3

我必須創建一個函數來爲我創建一組字符。我不確定我應該選擇以下哪種方法。 據我瞭解,我不應該使用createSet1,因爲如果在返回s之前出現錯誤,它將會泄漏。C++返回指針與返回std :: move的本地對象

set<char>* createSet1(){ 
    set<char>* s = new set<char>; 
    //does something 
    return s; 
} 

set<char> createSet2(){ 
    set<char> s; 
    //does something 
    return std::move(s); 
} 

unique_ptr<set<char>> createSet3(){ 
    unique_ptr<set<char>> s(new set<char>); 
    //does something 
    return s; 
} 

我會很高興,如果有人能解釋我應該更喜歡哪一個,爲什麼。

+3

沒有必要「說」'返回標準: :move(...)',因爲返回的值是一個右值。你真的明白了'unique_ptr'的情況(你注意到'unique_ptr'是隻移動嗎?) – sehe

+0

啊,好吧,我認爲std :: move是不必要的,如果它不是那些「聰明」指針(unique_ptr ,shared_ptr)。乾杯 –

回答

7

以上都不對:

std::set<char> createSet() { 
    std::set<char> s; 
    // do something 
    return s; 
} 

沒有理由動態分配設置,RVO會踢,刪除複製給你,而無需支付額外的動態分配和管理成本的記憶。


現在爲一組字符的具體問題,你可能會更好沒有使用一組所有,而是一個std::vector尺寸正確的:

class CharSet { 
    std::vector<bool> d_data; // std::vector<bool> quirks are fine here 
    void set(char ch, bool value) { 
     d_data[static_cast<unsigned char>(ch)] = value; 
    } 
public: 
    CharSet() : d_data(std::numeric_limits<unsigned char>::max()+1) {} 
    void set(char ch) { set(ch,true); } 
    void unset(char ch) { set(ch,false); } 
    bool isset(char ch) const { 
     return d_data[static_cast<unsigned char>(ch)]; 
    } 
}; 

這種方法的優點是您要支付的較高成本是std::set中節點的動態分配,並且與std::vector(對於足夠小的向量)情況下的每個分配相比,每個這樣的分配具有成本。 std::vector<bool>的內存將大致爲32個字節,這與64位體系結構上的std::set中的單個節點相當。你甚至可以使它成爲std::vector<char>以避免std::vector<bool>的怪癖,它將是256個字符,這是該集合中僅有幾個節點的成本。

0

std::set是一個容器,這意味着你可以返回它沒有問題,所以你可以修改你的第一個建議:

set<char> createSet1(){ 
    set<char> s; 
    //does something with s 
    return s; 
} 

希望這有助於