operator= 运算符重载,就类似正常我们为变量赋值(如a = b)时的情况,但是我们自己写的类,内部肯定有各种字段,赋值当然不会就像a=b那么简单啦。
如果我们自己写重载操作符=,编译器也会为我们生成一个,但是这个函数功能很弱,只能实现浅赋值。
// C++Test.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <iostream> #include <string> using namespace std; class CopyTest { private: string name; int id; public: CopyTest(int i, string n):id(i),name(n) { //cout<<"Construct!"<<endl; } ~CopyTest() { //cout<<"No"<<id<<" "<<"Destruct!"<<endl; } void Display() { cout<<name<<" "<<id<<endl; } }; int _tmain(int argc, _TCHAR* argv[]) { CopyTest test1(1, "hehe"); CopyTest test2(2, "haha"); cout<<"Before operator = test2 is: "; test2.Display(); test2 = test1; cout<<"After operator = test2 is "; test1.Display(); system("pause"); return 0; }
结果:
Before operator = test2 is: haha 2
After operator = test2 is hehe 1
请按任意键继续. . .
可见,虽然我们并没有写那个operator=的函数,但是我们仍然实现了对象的赋值。
// C++Test.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <iostream> #include <string> using namespace std; class CopyTest { private: string name; int id; public: CopyTest(int i, string n):id(i),name(n) { //cout<<"Construct!"<<endl; } ~CopyTest() { //cout<<"No"<<id<<" "<<"Destruct!"<<endl; } CopyTest& operator= (const CopyTest& e) { name = e.name; id = e.id; cout<<"operator= function is called!"<<endl; return *this; } void Display() { cout<<name<<" "<<id<<endl; } }; int _tmain(int argc, _TCHAR* argv[]) { CopyTest test1(1, "hehe"); CopyTest test2(2, "haha"); cout<<"Before operator = test2 is: "; test2.Display(); test2 = test1; cout<<"After operator = test2 is "; test1.Display(); system("pause"); return 0; }
a = b = c; //相当于: a = (b = c);即所谓的连锁赋值,赋值操作符必须返回一个reference指向操作符的左侧实参。
CopyTest& operator= (const CopyTest& e) { ... return *this; }
</pre><pre name="code" class="cpp">//在+=,-=,*=,/=等情况也都成立
// C++Test.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <iostream> #include <string> using namespace std; class CopyTest { private: string name; int id; int* pointer; public: CopyTest(int i, string n, int* p):id(i),name(n), pointer(p) { //cout<<"Construct!"<<endl; } ~CopyTest() { //cout<<"No"<<id<<" "<<"Destruct!"<<endl; } CopyTest& operator= (const CopyTest& e) { name = e.name; id = e.id; delete pointer; pointer = new int(*e.pointer); cout<<"operator= function is called!"<<endl; return *this; } void Display() { cout<<"name: "<<name<<" "<<"id: "<<id<<" pointer: "<<*pointer<<endl; } }; int _tmain(int argc, _TCHAR* argv[]) { CopyTest test1(1, "hehe", new int(1)); CopyTest test2(2, "haha", new int (2)); cout<<"Before operator = test2 is: "; test2.Display(); test2 = test1; cout<<"After operator = test2 is "; test1.Display(); system("pause"); return 0; }
test2 = test2;那么结果:
// C++Test.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <iostream> #include <string> using namespace std; class CopyTest { private: string name; int id; int* pointer; public: CopyTest(int i, string n, int* p):id(i),name(n), pointer(p) { //cout<<"Construct!"<<endl; } ~CopyTest() { //cout<<"No"<<id<<" "<<"Destruct!"<<endl; } CopyTest& operator= (const CopyTest& e) { if (this == &e) return *this; name = e.name; id = e.id; delete pointer; pointer = new int(*e.pointer); cout<<"operator= function is called!"<<endl; return *this; } void Display() { cout<<"name: "<<name<<" "<<"id: "<<id<<" pointer: "<<*pointer<<endl; } }; int _tmain(int argc, _TCHAR* argv[]) { CopyTest test1(1, "hehe", new int(1)); CopyTest test2(2, "haha", new int (2)); cout<<"Before operator = test2 is: "; test2.Display(); test2 = test2; cout<<"After operator = test2 is "; test2.Display(); system("pause"); return 0; }
CopyTest& operator= (const CopyTest& e) { if (this == &e) return *this; name = e.name; id = e.id; //先用一个临时指针变量存储 int* tempPointer = new int (*e.pointer); //如果上一步执行成功,才删除原有内容 delete pointer; //赋值 pointer = tempPointer; cout<<"operator= function is called!"<<endl; return *this; }
// C++Test.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <iostream> #include <string> using namespace std; class CopyTest { private: string name; int id; int* pointer; public: CopyTest(int i, string n, int* p):id(i),name(n), pointer(p) { //cout<<"Construct!"<<endl; } ~CopyTest() { //cout<<"No"<<id<<" "<<"Destruct!"<<endl; } //拷贝构造函数 CopyTest(const CopyTest& e) { name = e.name; id = e.id; pointer = new int (); *pointer = *e.pointer; cout<<"Copy Construct is called!"<<endl; } CopyTest& operator= (const CopyTest& e) { CopyTest temp(e); std::swap(*this, temp); cout<<"operator= function is called!"<<endl; return *this; } void Display() { cout<<"name: "<<name<<" "<<"id: "<<id<<" pointer: "<<*pointer<<endl; } }; int _tmain(int argc, _TCHAR* argv[]) { CopyTest test1(1, "hehe", new int(1)); CopyTest test2(2, "haha", new int (2)); cout<<"Before operator = test2 is: "; test2.Display(); test2 = test1; cout<<"After operator = test2 is "; test2.Display(); system("pause"); return 0; }不过,这里我的 程序会不停的调用swap函数,直到stack overflow...查了半天也没差出来,以后来填坑。
CopyTest& operator= (CopyTest& e) { std::swap(*this, e); cout<<"operator= function is called!"<<endl; return *this; }直接使用函数的实参,来作为swap的参数,但是注意要把const去掉。
// C++Test.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <iostream> #include <string> using namespace std; class CopyTest { private: string name; int id; public: CopyTest(int i, string n):id(i),name(n) { //cout<<"Construct!"<<endl; } ~CopyTest() { //cout<<"No"<<id<<" "<<"Destruct!"<<endl; } //拷贝构造函数 CopyTest(const CopyTest& e) { name = e.name; id = e.id; cout<<"Copy Construct is called!"<<endl; } CopyTest& operator= (CopyTest& e) { if (this == &e) return *this; name = e.name; //id = e.id;如果我们忘记写这一句,编译器并不会报错 cout<<"operator= function is called!"<<endl; return *this; } void Display() { cout<<"name: "<<name<<" "<<"id: "<<id<<endl; } }; int _tmain(int argc, _TCHAR* argv[]) { CopyTest test1(1, "hehe"); CopyTest test2(2, "haha"); cout<<"Before operator = test2 is: "; test2.Display(); test2 = test1; cout<<"After operator = test2 is "; test2.Display(); system("pause"); return 0; }结果:
// C++Test.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <iostream> #include <string> using namespace std; class CopyTest { private: string name; int id; public: CopyTest(int i, string n):id(i),name(n) { //cout<<"Construct!"<<endl; } ~CopyTest() { //cout<<"No"<<id<<" "<<"Destruct!"<<endl; } //拷贝构造函数 CopyTest(const CopyTest& e) { name = e.name; id = e.id; cout<<"CopyTest CopyConstructor is called!"<<endl; } CopyTest& operator= (const CopyTest& e) { if (this == &e) return *this; name = e.name; id = e.id; cout<<"CopyTest operator= function is called!"<<endl; return *this; } virtual void Display() { cout<<"name: "<<name<<" "<<"id: "<<id<<endl; } }; class CopyTestChild : public CopyTest { private: int childId; public: CopyTestChild(int i, string n, int ci): CopyTest(i, n), childId(ci) { //cout<<"CopyTestCilid is Constructed!"<<endl; } ~CopyTestChild() { } //子类拷贝构造函数调用基类拷贝构造函数 CopyTestChild(const CopyTestChild& e) : CopyTest(e) { childId = e.childId; cout<<"CopyTestChild CopyConstructor is called!"<<endl; } CopyTestChild& operator= (const CopyTestChild& e) { if (this == &e) return *this; //调用基类operator=函数 CopyTest::operator=(e); childId = e.childId; cout<<"CopyTestChild operator= function is called!"<<endl; return *this; } virtual void Display() { CopyTest::Display(); cout<<"ChildId is "<<childId<<endl; } }; int _tmain(int argc, _TCHAR* argv[]) { CopyTestChild test1(1, "hehe", 1); CopyTestChild test2(2, "haha", 2); cout<<"Before operator = test2 is: "; test2.Display(); test2 = test1; cout<<"After operator = test2 is "; test2.Display(); system("pause"); return 0; }结果:
int _tmain(int argc, _TCHAR* argv[]) { CopyTestChild test1(1, "hehe", 1); CopyTestChild test2(test1); test2.Display(); system("pause"); return 0; }