什么時候調用:拷貝構造函數、賦值運算符


class Person
{
public:

    Person(const Person& p);

    Person& operator=(const Person& p);

private:
    int age;
    string name;
};

在默認情況下(用戶沒有定義,但是也沒有顯式的刪除),編譯器會自動的隱式生成一個拷貝構造函數和賦值運算符。

但用戶可以使用delete來指定不生成拷貝構造函數和賦值運算符,這樣的對象就不能通過值傳遞,也不能進行賦值運算。

Person(const Person& p) = delete;

 

 

注意:拷貝構造函數必須以引用的方式傳遞參數。這是因為,在值傳遞的方式傳遞給一個函數的時候,會調用拷貝構造函數生成函數的實參。

如果拷貝構造函數的參數仍然是以值的方式,就會無限循環的調用下去,直到函數的棧溢出。

(不用引用,編譯不能通過)

 

何時調用

拷貝構造函數和賦值運算符的行為比較相似,都是將一個對象的值復制給另一個對象;但是其結果卻有些不同,

拷貝構造函數使用傳入對象的值生成一個新的對象的實例,而賦值運算符是將對象的值復制給一個已經存在的實例

這種區別從兩者的名字也可以很輕易的分辨出來,拷貝構造函數也是一種構造函數,那么它的功能就是創建一個新的對象實例;賦值運算符是執行某種運算,將一個對象的值復制給一個已經存在的實例

調用的是拷貝構造函數還是賦值運算符,主要是看是否有新的對象實例產生。如果產生了新的對象實例,那調用的就是拷貝構造函數;如果沒有,那就是對已有的對象賦值,調用的是賦值運算符。

 

調用拷貝構造函數主要有以下場景:

  • 對象作為函數的參數,以值傳遞的方式傳給函數。 
  • 對象作為函數的返回值,以值的方式從函數返回
  • 使用一個對象給另一個對象初始化

 

A print(int n)
{
    A a(1);
    return a;
}

A aa = print(2332);

下方的示例一樣,

A print(int n)
{
    A a(1);
    return a;
}


print(2332);

不管有沒有設置返回值,在返回時都會調用拷貝構造函數:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM