如何正确释放返回值

时间:2017-06-11 09:08:38

标签: c++ memory-leaks return-value

我需要为我的班级创建一个+运算符,我这样做:

class CDoubleString{
public:
   string textA="";
   string textB="";
   CDoubleString(string x,string y) : textA(x),textB(y){}

   CDoubleString & operator + (const CDoubleString & y){
       CDoubleString * n=new CDoubleString(textA,textB);
       n->textA+=y.textA;
       n->textB+=y.textB;
       delete n;
       return *n;
   }
}

它似乎按预期工作,但我发现释放内存存在问题。在我退回的那一刻,它已经可能是别的了。所以这是不明确的行为,我是否正确? 如何避免?

2 个答案:

答案 0 :(得分:3)

  

所以它是未定义的行为,我是否正确?

  

如何避免?

有几种方法。

  1. 按值返回

    CDoubleString operator + (const CDoubleString & y){
        CDoubleString n(textA,textB);
        n.textA+=y.textA;
        n.textB+=y.textB;
        return n;
    }
    
  2. 返回std::unique_ptr

    std::unique_ptr<CDoubleString> operator + (const CDoubleString & y){
        std::unique_ptr<CDoubleString> n = std::make_unique<CDoubleString>(textA,textB);
        n->textA+=y.textA;
        n->textB+=y.textB;
        return n;
    }
    
  3. 我更喜欢你的第一个变种。对于大多数现代编译器,您可以依赖RVO和copyelistion,因此您不必担心所制作的其他副本。

答案 1 :(得分:1)

  

所以它是未定义的行为,我是否正确?

是的,但不完全是你想的原因。您正在返回对已删除对象的引用,并且该引用无效并且具有未定义的行为。但是&#34;它已经可能是其他东西&#34;适用于调用者,因为调用者实际上最终会从该死对象中读取,并且即使您要延迟删除对象,这可能会导致问题:您可能仍然不要拖延得太久。

  

如何避免?

按价值返回可能是最简单的。

CDoubleString operator + (const CDoubleString & y){
    CDoubleString n(textA,textB);
    n.textA+=y.textA;
    n.textB+=y.textB;
    return n;
}