zoukankan      html  css  js  c++  java
  • When should we write our own assignment operator in C++?

      The answer is same as Copy Constructor. If a class doesn’t contain pointers, then there is no need to write assignment operator and copy constructor. The compiler creates a default copy constructor and assignment operators for every class.

      The compiler created copy constructor and assignment operator may not be sufficient when we have pointers or any run time allocation of resource like file handle, a network connection..etc. For example, consider the following program.

     1 #include<iostream>
     2 using namespace std;
     3 
     4 // A class without user defined assignment operator
     5 class Test
     6 {
     7     int *ptr;
     8 public:
     9     Test (int i = 0)      
    10     { 
    11         ptr = new int(i); 
    12     }
    13     void setValue (int i) 
    14     { 
    15         *ptr = i; 
    16     }
    17     void print()          
    18     { 
    19         cout << *ptr << endl; 
    20     }
    21 };
    22 
    23 int main()
    24 {
    25     Test t1(5);
    26     Test t2;
    27     t2 = t1;
    28     t1.setValue(10);
    29     t2.print();
    30     return 0;
    31 }

      Output of above program is “10″.

      If we take a look at main(), we modified ‘t1′ using setValue() function, but the changes are also reflected in object ‘t2′. This type of unexpected changes cause problems.
      Since there is no user defined assignment operator in the above program, compiler creates a default assignment operator, which copies ‘ptr’ of right hand side to left hand side. So both ‘ptr’s start pointing to the same location.

      We can handle the above problem in two ways.

      1) Do not allow assignment of one object to other object. We can create our own dummy assignment operator and make it private.

      2) Write your own assignment operator that does deep copy.

      

      Same is true for Copy Constructor.

      Following is an example of overloading assignment operator for the above class.

     1 #include<iostream>
     2 using namespace std;
     3 
     4 class Test
     5 {
     6     int *ptr;
     7 public:
     8     Test (int i = 0)      
     9     { 
    10         ptr = new int(i); 
    11     }
    12     void setValue (int i) 
    13     { 
    14         *ptr = i; 
    15     }
    16     void print()          
    17     { 
    18         cout << *ptr << endl; 
    19     }
    20     Test & operator = (const Test &t);
    21 };
    22 
    23 Test & Test::operator = (const Test &t)
    24 {
    25     // Check for self assignment
    26     if(this != &t)
    27     {
    28         *ptr = *(t.ptr);
    29     }
    30     
    31     return *this;
    32 }
    33 
    34 int main()
    35 {
    36     Test t1(5);
    37     Test t2;
    38     t2 = t1;
    39     t1.setValue(10);
    40     t2.print();
    41     return 0;
    42 }

      Output:5
      

      We should also add a copy constructor to the above class, so that the statements like “Test t3 = t4;” also don’t cause any problem.

      Note the if condition in assignment operator. While overloading assignment operator, we must check for self assignment(认同测试). Otherwise assigning an object to itself may lead to unexpected results (See this). Self assignment check is not necessary for the above ‘Test’ class, because ‘ptr’ always points to one integer and we may reuse the same memory.

      But in general, it is a recommended practice to do self-assignment check.

      补充:

      C++ doesn't allow default assignment operator to be used when there is a reference in your class.

      For example, the following program produces error "error C2582: 'Test' : 'operator =' function is unavailable".

     1 #include<iostream>
     2 using namespace std;
     3 
     4 
     5 class Test
     6 {
     7     int x;
     8     int &ref;
     9 public:
    10     Test (int i):x(i),ref(x) 
    11     {
    12     }
    13     void print() 
    14     { 
    15         cout << ref; 
    16     }
    17     void setX(int i) 
    18     { 
    19         x = i; 
    20     }
    21     //Test &operator = (const Test &t) {x = t.x;}
    22 };
    23 
    24 
    25 int main()
    26 {
    27     Test t1(10);
    28     Test t2(20);
    29     t2 = t1;
    30     t1.setX(40);
    31     t2.print();
    32     return 0;
    33 }

      If you uncomment the operator definition in the above program, the program works fine and prints "10".
      So compiler forces to write an assignment operator when you have a non-static reference in your class.

      Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.

      转载请注明:http://www.cnblogs.com/iloveyouforever/

      2013-11-26  21:35:48

  • 相关阅读:
    IOS 推送消息 php做推送服务端
    判断是否是iPhone5
    BeeFramework
    如何在类中获取request,和网站路径
    maven build 报release 400错误
    mysql启动问题access denied for user 'root'@'localhost'(using password:YES)
    adapter结构异常记录
    eclipse项目报红解决
    Location Type Project 'testma' is missing required source folder: 'src/test/resources' testma Build
    当遇到eclipse调试断点乱走数据不准确的时候,请maven clean,maven install
  • 原文地址:https://www.cnblogs.com/iloveyouforever/p/3444332.html
Copyright © 2011-2022 走看看