1. 程式人生 > >C++庫研究筆記——賦值操作符operator=的正確過載方式(三個準則)

C++庫研究筆記——賦值操作符operator=的正確過載方式(三個準則)

最終設計:

  MyClass& MyClass::operator=(const MyClass &rhs) {
    // Check for self-assignment!
    if (this == &rhs)      // Same object?
      return *this;        // Yes, so skip assignment, and just return *this.

    ... // Deallocate, allocate new space, copy values...
    return *this;
  }


設計要求:
  a, b, c, d, e;


  a = b = c = d = e = 42;
This is interpreted by the compiler as:
  a = (b = (c = (d = (e = 42))));
  MyClass a, b, c;
  ...
  (a = b) = c;  // What??
  // Take a const-reference to the right-hand side of the assignment.
  // Return a non-const reference to the left-hand side.
//對應上條
  MyClass& MyClass::operator=(const MyClass &rhs) {
    ...  // Do the assignment operation!


    return *this;  // Return a reference to myself.
  }

  MyClass& MyClass::operator=(const MyClass &rhs) {
    // 1.  Deallocate any memory that MyClass is using internally
    // 2.  Allocate some memory to hold the contents of rhs
    // 3.  Copy the values from rhs into this instance
    // 4.  Return *this
  }
但上述設計仍然不完整,a=a會出現什麼情況? 當然還要考慮效能問題

  MyClass mc;
  ...
  mc = mc;     // BLAMMO.
 CHECK FOR SELF-ASSIGNMENT.



所以正確且安全的設計如下:So, the correct and safe version of the MyClass assignment operator would be this:
  MyClass& MyClass::operator=(const MyClass &rhs) {
    // Check for self-assignment!
    if (this == &rhs)      // Same object?
      return *this;        // Yes, so skip assignment, and just return *this.

    ... // Deallocate, allocate new space, copy values...
    return *this;
  }

或者:

  MyClass& MyClass::operator=(const MyClass &rhs) {
    // Only do assignment if RHS is a different object from this.
    if (this != &rhs) {
      ... // Deallocate, allocate new space, copy values...
    }
    return *this;
  }
總之,過載操作符的三個準則
1.右端值要為const 型別(不想改變他的值)Take a const-reference for the argument (the right-hand side of the assignment).
2.要返回一個引用,以便於實現(a=b=c…… (Do this by returning *this.)

3.檢查是否為自我賦值Check for self-assignment, by comparing the pointers (this to &rhs).

-----------------------------------------------------

類似的,我們可以設計這樣的運等符(資料傳輸)
a<<(b<<c) 與上文一樣的
當然如果我們只允許a<<b非連鎖的操作(指a<<b<<c不允許),我們可以拋棄掉規則2
  void MyClass::operator=(const MyClass &rhs) {
    // Only do assignment if RHS is a different object from this.
    if (this != &rhs) {
      ... // Deallocate, allocate new space, copy values...
    }
    return *this;
  }