运算符重载问题

时间:2011-12-08 02:38:10

标签: c++ operator-overloading

目前我正在尝试为我编写的名为mystring的类重写+ =运算符:

MyString& operator+=(MyString& s1, const MyString& s2)
{

    int newStringLength = s1.length + s2.length;
    char* newStorage = new char[newStringLength +  1];

    strcpy(newStorage, s1.data);

    strcpy(newStorage + s1.length, s2.data);
    delete[] s1.data;

    s1.length = newStringLength;
    s1.data = newStorage;

    return s1;

}

MyString operator+(const MyString& s1, const MyString& s2)
{

    MyString temp;
    delete[] temp.data;

    temp.length = s1.length;
    temp.data = new char[temp.length+1];

    strcpy(temp.data, s1.data);
    temp+=s2;

    return temp;

}

其中length是字符串的长度,data是以char *格式存储的字符串。

当我尝试做类似的事情时,程序运行正常:

MyString test1 = "hi";
MyString test2 = "to"; 

test1 += test2;

但是当我尝试这样的事情时,它不起作用:

   MyString test;
    MyString test1 = "hi";
    MyString test2 = "to"; 

    test += test2 + test1
          += "you";

基本上当我开始以交替方式混合+ =和+时,它不起作用。这是编译时的错误:

testoutput.cpp:26: error: no match for ‘operator+=’ in ‘operator+(const MyString&, const MyString&)(((const MyString&)((const MyString*)(& test1)))) += "you"’
mystring.h:45: note: candidates are: MyString& operator+=(MyString&, const MyString&)

有没有人知道如何更改我的代码才能实现此功能?

2 个答案:

答案 0 :(得分:3)

以这种方式混合++=是没有意义的。我不确定您的预期行为是什么,但如果您希望嵌套+=应用于test1,则必须使用括号:

test += test2 + (test1 += "you");

这不是您的赋值运算符的问题,而是语言中的运算符优先级。如果您将MyString替换为int,则会遇到同样的问题。

++=运算符的precedence and associativity会导致不带括号的表达式被解释为:

test += ((test2 + test1) += "you");

这会尝试分配给test2 + test1,但这是不可能的(您只能分配给变量)。此运算符优先级不能更改,如果没有括号,表达式将始终以这种方式解释。

答案 1 :(得分:0)

你的错误在这里:

test += test2 + test1 += "you";

程序将从'test2 + test1'创建临时对象,并为其调用operator + =()。问题是,在一个表达式中有2个operator + =调用,并且未定义哪个将首先调用。因此,运算符+ =(TemporaryObject,MyString(“you”))的结果可能会丢失;

为了防止这种情况,你应该像这样声明operator +:

const MyString operator+(const MyString& s1, const MyString& s2)

如果你这样做,编译器将能够发出错误,如果它偶然发现这样的表达式具有不可预测的结果;

编辑:

现在我们有了编译器输出,我看到编译器足够聪明,可以看到从operator +()创建的对象是临时的。所以,你只需要制作2个表达式而不是1:

test += test2 + test1;
test += "you";

但我仍建议从运算符+();

返回const对象