与类控制其对象如何初始化一样,类也可以控制对象如何赋值:
Foo a,b; // 定义Foo类型的两个对象a,b
a = b; // 使用Foo的拷贝运算符进行赋值
1. 重载赋值运算符
重载运算符本质上是一个函数,由operator关键字后接要定义的运算符的符号组成。
赋值运算符是由一个名为"operator="的函数。类似于其他任何函数,运算符函数也有一个返回类型和参数列表。
class Foo
{
public:
Foo &operator=(const Foo &); // 赋值运算符
}
为了与内置类型的赋值保持一致,赋值运算符通常返回一个指向其左侧运算对象的引用。标准库通常要求保存在容器中的类型要具有赋值运算符,且其返回值是左侧运算对象的引用
2. 合成拷贝赋值运算符
与处理拷贝构造函数一样,如果一个未定义自己的拷贝赋值运算符,编译器会为它生成一个默认的合成拷贝赋值运算符。它将右侧运算对象的每一个非static成员赋予左侧运算对象的对应成员。。
class Foo
{
public:
Foo &operator=(const Foo &); // 赋值运算符
int a;
string b;
}
Foo &Foo::operator=(const Foo & f)
{
a = f.a; // 使用内置的int赋值
b = f.b; // 调用string::operator=
return *this; // 返回一个此对象的引用
}
3. 拷贝运算符与拷贝构造函数使用的区别
#include <iostream>
#include <string>
using namespace std;
class Foo
{
public:
Foo &operator=(const Foo &)
{
printf("拷贝构造。。");
}
Foo(const Foo& a)
{
printf("拷贝运算符。。");
}
Foo()
{
}
};
int main()
{
Foo a;
Foo b = a; // 调用拷贝构造函数。
b = a; // 调用拷贝赋值运算符
}
虽然都是用 = 。但是拷贝构造函数,用在定义时,用于初始化。而拷贝赋值运算符,是用于赋值。
参考:《C++ primer》整理笔记