c ++返回指针与使用std :: move返回本地对象

Rob*_*oll 3 c++ memory-management

我必须创建一个为我创建一组字符的函数.我不确定我应该选择以下哪种方法.据我所知,我不应该使用createSet1,因为如果在返回s之前出现问题,它将会泄漏.

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;
}
Run Code Online (Sandbox Code Playgroud)

如果有人可以解释我应该选择哪一个以及为什么,我会很高兴.

Dav*_*eas 7

以上都不是:

std::set<char> createSet() {
   std::set<char> s;
   // do something
   return s;
}
Run Code Online (Sandbox Code Playgroud)

没有理由动态分配集合,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)];
   }
};
Run Code Online (Sandbox Code Playgroud)

这种方法的优点是您要支付的成本较高的是动态分配的节点std::set,并且每个这样的分配与单个分配相比具有成本std::vector(对于足够小的向量).该内存std::vector<bool>大约为32个字节,与std::set64位架构中的单个节点相当.你甚至可以做到这一点,std::vector<char>以避免它的怪癖,std::vector<bool>它将是256个字符,这是集合中只有几个节点的成本.