参考:https://blog.csdn.net/K346K346/article/details/46943875
链式操作:
链式操作是利用运算符进行的连续运算(操作),它的特点是一条语句中出现两个或两个以上相同的操作符,如连续的赋值操作、连续的输入操作、连续的输出操作、连续的相加操作等都是链式操作。
类的链式操作:
为了实现类的链式操作,操作符的重载必须满足一定的要求:
1、操作符重载函数一定不能返回void类型。
因为void类型不能参与任何运算,所以,操作符重载函数返回void类型实际上是阻止了链式操作的可能。
2、对赋值操作符进行重载,如果返回的是类的对象,那么链式赋值操作必须借助于拷贝构造函数才能进行。会有较大的运行开销。
范例:
这边利用实现String类的方式来说明一下。
首先看如果是操作运算符返回类的对象:
#include <iostream>
#include <string.h>
using namespace std;
class String
{
public:
String();
String(const char *);
String(const String &other);
String operator=(const String &other);
friend ostream& operator<<(ostream& out, const String &s);
~String();
private:
char *data;
};
String::String()
{
data = new char[1];
data = '\0';
}
String::String(const char *str)
{
int length = strlen(str) + 1;
data = new char[length];
memset(data, 0, length);
strcpy(data, str);
}
String::String(const String &other)
{
cout<<"construct String!"<<endl;
int length = strlen(other.data) + 1;
data = new char[length];
memset(data, 0, length);
strcpy(data, other.data);
}
String::~String()
{
delete[] data;
}
String String::operator=(const String &other)
{
if(this == &other)
{
return *this;
}
int length = strlen(other.data) + 1;
delete[] data;
data = new char[length];
memset(data, 0, length);
strcpy(data, other.data);
return *this;
}
ostream& operator<<(ostream& out, const String &s)
{
out<<s.data;
return out;
}
int main()
{
String s1 = "hello";
String s2 = "world";
String s3;
s3 = s1 = s2;
cout<<s3<<endl;
}
查看结果:
[admin@localhost tmp]$ ./test
construct String!
construct String!
world
定义了3个String类的对象,进行赋值操作时,先执行s1=s2,调用了一次拷贝构造函数,再将(s1=s2)的结果赋值给s3时,又执行了一次拷贝构造函数。
接下来我们将String String::operator=(const String &other)改为
String& String::operator=(const String &other)看会打印成什么样的结果。
声明、定义:
String& operator=(const String &other);
String& String::operator=(const String &other)
{
if(this == &other)
{
return *this;
}
int length = strlen(other.data) + 1;
delete[] data;
data = new char[length];
memset(data, 0, length);
strcpy(data, other.data);
return *this;
}
结果:
[admin@localhost tmp]$ ./test
world
一次拷贝构造函数都没有调用,因为赋值运算符操作符函数返回了String类的引用,不会产生类的对象,也就减少了运算消耗,所以,赋值运算符重载几乎无一例外地返回引用。