簡體   English   中英

為什么在調用重載的賦值運算符時調用了拷貝構造函數?

[英]why copy constructor is called at the time of calling overloaded assignment operator?

我試圖了解構造函數和賦值運算符的用法。 我正在嘗試下面的程序。

#include <iostream>
using namespace std;

class myclass {
    int x;
public:
    myclass (int p) {
        cout << "calling constructor" << endl;
        x = p;
    }
    myclass () {
        cout << "calling constructor with no arguments" << endl;
        x = 0;
    }
    myclass (myclass &t) {
        cout << "calling copy constructor" << endl;
        x = t.x;
    }

    myclass operator=(myclass &t) {
        cout << "calling assignment operator" << endl;
        x = t.x;
        return *this;
    }

    void show () {
        cout << "val = " << x << endl;
    }
};


int main() {
    myclass a1;
    a1.show();
    myclass a2 = a1;
    a2.show();
    myclass a3(a2);
    a3.show();
    myclass a4(200);
    a2 = a4;
    a2.show();
    return 0;
}

輸出:

calling constructor with no arguments // call 1
val = 0
calling copy constructor // call 2
val = 0
calling copy constructor // call 3
val = 0
calling constructor // call 4
calling assignment operator // call 5
calling copy constructor // call 6 i am not able to understand this print line
val = 200

調用1是從myclass a1完成的;

調用2是從myclass a2 = a1完成的;

調用3,是從myclass a3(a2)完成的;

調用4是從myclass a4(200)完成的;

調用5是從a2 = a4完成的;

但是我無法獲得呼叫6的來源,它是從指令中調用的:

a2 = a4;

但是,它將如何調用復制構造函數?

任何幫助/指針將是一個很大的幫助。 我正在從c潛入cpp,因此請多多包涵。

(您復制的構造函數和賦值運算符的格式略有錯誤:它們應將const引用作為參數,而賦值運算符應返回引用而不是值)。

myclass a2 = a1; a2尚不存在。 因此,調用復制構造函數使用a1創建a2

但是對於a2 = a4a2已經存在,因此使用賦值運算符 a2 分配a4

因此,規則本質上是:如果對象不存在,則需要對其進行構造。 您可以通過應用此規則來解釋觀察到的輸出。

 myclass operator=(myclass &t) {
    cout << "calling assignment operator" << endl;
    x = t.x;
    return *this;
}

上面的函數按值返回。 按值返回是調用復制構造函數的情況之一。 同樣是AFAIK,這並不總是正確的(通過調用復制構造函數的值返回),因為某些編譯器實現了返回值優化。

更改為

myclass& operator=(myclass &t)

然后:

calling constructor with no arguments
val = 0
calling copy constructor
val = 0
calling copy constructor
val = 0
calling constructor
calling assignment operator
val = 200

如果按值返回,則將調用復制ctor。 通過引用返回以避免調用副本ctor。

您的賦值運算符按value返回,因此返回時還有另一個副本。

那是第六個電話的來歷。

通常,賦值運算符返回一個引用 ,因此,當您return *this ,實際上確實會返回*this

myclass& operator=(myclass &t) {
//     ^

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM