我需要为我的班级创建一个+运算符,我这样做:
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;
}
}
它似乎按预期工作,但我发现释放内存存在问题。在我退回的那一刻,它已经可能是别的了。所以这是不明确的行为,我是否正确? 如何避免?
答案 0 :(得分:3)
所以它是未定义的行为,我是否正确?
是
如何避免?
有几种方法。
按值返回
CDoubleString operator + (const CDoubleString & y){
CDoubleString n(textA,textB);
n.textA+=y.textA;
n.textB+=y.textB;
return n;
}
返回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;
}
我更喜欢你的第一个变种。对于大多数现代编译器,您可以依赖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;
}