C++三大函數(The Big Three)

C++三大函數(The Big Three)

C++三大函數:html

  • 析構函數
  • 複製構造函數
  • operator=

析構函數

函數模樣:~S()ide

當一個對象超出做用域或執行delete的時候,析構函數就被調用。函數

複製構造函數

函數模樣:S(const S& s)this

如下狀況,複製構造函數均會被調用:spa

  • 聲明的同時初始化:指針

    S s1 = s2;  //注意此時雖然出現=,可是不是調用operator=哦
    S s1(s2);
  • 調用函數時使用按值傳遞(而不是按引用傳遞)code

    void f(S s);
    S s1;
    f(s1);
  • 經過值返回對象htm

    S f()
    {
        S s1;
        return s1;
    }

operator=

函數模樣:const S& operator=(const S& s)對象

當=應用於兩個已經構造的對象時,就調用複製賦值運算符operator=。blog

S s1;
s1 = s2;    //注意與S s1 = s2; 的區別

注意事項:

  1. 三大函數不手動實現的時候,會使用默認的版本。好比operator=的默認版本會依次爲數據成員複製,若是是基本數據類型天然沒什麼問題,但當數據成員含有指針的時候,operator的只會進行淺複製,即只是指針自己被複制,而不是指針所指向的內容被複制。見下例。

    class S
    {
        public:
        int *p;
        S(int x=0){p=new int(x);}
    };
    void f()
    {
        S s1(2), s2;
        S s3 = s1;
        s2 = s1;
        *s1.p=3;
        cout << *s1.p << ' '<< *s2.p << ' ' << *s3.p << endl;//3 3 3
    }

    很明顯這不是咱們想要的,咱們想讓不一樣的對象的值不互相影響,此時須要實現深複製,見下例。

    class S
    {
        public:
        int *p;
        S(int x=0){p=new int(x);}
        S(const S& rhs)
        {
            p = new int(*rhs.p);
        }
        const S& operator=(const S& rhs)    //rhs=right-hand side
        {
            if (this != &rhs)   //檢查是否複製自身 
                *p = *rhs.p;
            return *this;
        }
    };
    void f()
    {
        S s1(2), s2;
        S s3 = s1;
        s2 = s1;
        *s1.p=3;
        cout << *s1.p << ' '<< *s2.p << ' ' << *s3.p << endl;   //3 2 2
    }
相關文章
相關標籤/搜索