2013-11-15 5 views
3

Мне нужно создать функцию, которая создает набор символов для меня. Я не уверен, какой из следующих подходов я должен предпочесть. Насколько я понял, я не должен использовать createSet1, потому что, если что-то пойдет не так, прежде чем вернуться, он будет течь.C++ return pointer vs. return local object with 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 (...) ', поскольку возвращаемое значение является неявным значением r. Вы действительно получили это право в случае '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; 
} 

Там нет причин для динамического распределения множества, РВО будет удар и удалить копию для вас, без необходимости оплаты стоимости дополнительного динамического распределения и управления этой памяти.


Теперь для конкретной задачи набора символов, вы могли бы быть лучше не использовать набор вообще, а скорее 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 байта, что сопоставимо с одним узлом в std::set по 64-битной архитектуре. Вы даже можете сделать это std::vector<char>, чтобы избежать причуд std::vector<bool>, и это будет 256 символов, стоимость которых составляет всего несколько узлов в наборе.

0

std::set является контейнером, а это означает, что вы можете вернуть его без проблем, так что вы можете изменить свое первое предложения:

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

Надеется, что это помогает