C++ 返回指针与返回带有 std::move 的本地对象

c++ return pointer vs. return a local object with std::move

本文关键字:返回 move 对象 std 指针 C++      更新时间:2023-10-16

我必须创建一个函数来为我创建一组字符。我不确定我应该选择以下哪种方法。据我了解,我不应该使用 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;
}

如果有人能解释我应该更喜欢哪一个以及为什么,我会很高兴。

以上

都不是:

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<bool>怪癖的std::vector<char>,它将是 256 个字符,这是集合中几个节点的成本。

std::set是一个

容器,这意味着您可以毫无问题地返回它,因此您可以将第一个提案修改为:

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

希望这有帮助