返回引用实例和非引用实例(return mystr & vs mystr)之间的区别是什么?



这里是mystr

结构体
#include <stdio.h>
#include <string.h>
struct mystr {
char *str;
mystr(const char *s) {
str = new char[strlen(s) + 1];
strcpy(str, s);
printf("[1]%sn", s);
}
mystr(const mystr &s) {
str = new char[strlen(s.str) + 1];
strcpy(str, s.str);
}
~mystr() {
delete[] str;
}
void printn() const {
printf("%sn", str);
}
//mystr& operator+=(const char *s) this line works!
mystr operator+=(const char *s) {
char *old = str;
int len = strlen(str) + strlen(s);
str = new char[len + 1];
strcpy(str, old);
strcat(str, s);
printf("[2]%s,%s,%sn", old, s, str);
delete[] old;
return *this;
}
};

这是主要代码

int main() {
mystr s = "abc";
(s += "def") += "ghi";
// only print  s = abcdef
// when put & before operator+=, it prints s = abcdefghi
printf("s = %sn", s.str); 
}

问题

两者之间有什么区别 Return Mystr & VS Mystr? 我看到运算符+=被调用了两次,但输出是不同的。 在 C++ 中,返回实例中的行为是什么?

区别在于是否返回副本或引用。

有了这个:

mystr operator+=(const char*) {/* some code */ return *this;}

返回this对象的副本。

有了这个:

mystr& operator+=(const char*) {/* some code */ return *this;}

返回对this对象的引用。

当您返回副本时,请执行以下操作:

(s += "def") += "ghi";

不会"ghi"添加到s,而是添加到它的副本中,s保持不变。

你可以让你的mystr(const mystr &s)复制构造函数(可能是析构函数(也打印出一些东西来查看差异。

您询问的差异是由于返回需要分配给左侧变量的临时计算值。因此,您必须通过返回引用(mystr&(继续分配链。 如果按值(mystr(返回,则它会中断赋值链。

X& operator+=(const X& rhs) // compound assignment (does not need to be a member,
{                           // but often is, to modify the private members)
/* addition of rhs to *this takes place here */
return *this; // return the result by reference
}

https://en.cppreference.com/w/cpp/language/operator_assignment

实际上,每当我们使操作员超载时,其开发人员都有责任保持操作员的行为与语言中提到的相同。当我们开发可供数千名用户使用的代码时,每个人都没有时间检查我们代码的实现。

最小惊讶原则意味着系统的组件应该以大多数用户期望的方式运行;该行为不应使用户感到惊讶或惊讶。

运算符重载的基本规则和习语是什么?

最新更新