複製構造函數必須加const的情形、編譯器優化的情形和調用移動構造函數的情形

以下情況都會調用拷貝構造函數:
① 程序中需要新建立一個對象,並用另一個同類的對象對它初始化。
② 當函數的參數爲類的對象時。在調用函數時需要將實參對象傳遞給形參,也就是需要建立一個實參的拷貝,這就是按實參複製一個形參,系統是通過調用複製構造函數來實現的,這樣能保證形參具有和實參完全相同的值。
③ 函數的返回值是類的對象。在函數調用完畢將返回值帶回函數調用處時,需要將函數中的對象複製一個臨時對象並傳給該函數的調用處。
注意:對已經初始化過的對象直接賦值,不會調用複製構造函數
下面來上實例:

#include <iostream>

using namespace std;
class Point
{
    int x,y;
public:
    Point(){cout<<"default construct"<<endl;}
    Point(int a,int b):x(a),y(b){cout<<"construct"<<endl;}
    Point(/*注意這裏不加const是正確的*/Point &p):x(p.x),y(p.y){cout<<"copy"<<endl;}
};
Point fun(Point p)
{
    return p;
}
int main()
{
    Point a(1,2);
    Point b;
    b=fun(a);
    return 0;
}

在這裏插入圖片描述
這和一開始的理論吻合,第一次形實結合時調用了複製構造函數,第二次在返回時先調用複製構造函數開闢了一塊臨時空間儲存返回的對象,然後把臨時對象賦值給b。共調用2次。

#include <iostream>

using namespace std;
class Point
{
    int x, y;
public:
    Point() { cout << "default construct" << endl; }
    Point(int a, int b) :x(a), y(b) { cout << "construct" << endl; }
    Point( const/*此程序必須加const*/ Point& p) :x(p.x), y(p.y) { cout << "copy" << endl; }
};
Point fun(Point p)
{
    return p;
}
int main()
{
    Point a(1, 2);
    Point b=fun(a);//直接初始化
    return 0;
}

在這裏插入圖片描述
複製構造函數調用了兩次,第一次是形實結合時,第二次是用返回值初始化b時,爲什麼定義複製構造函數必須加const呢?因爲返回值是一個常量,該常量作爲複製構造函數的參數,而常量不可以作爲變量的引用。
那麼問題又來了,爲什麼函數的返回值是類的對象,卻沒有調用複製構造函數呢?
答案是:編譯器自動進行了優化,避免多調用一次複製構造函數。

#include <iostream>

using namespace std;
class Point
{
    int x, y;
public:
    Point() { cout << "default construct" << endl; }
    Point(Point&& p) { cout << "move" << endl; }
    Point(int a, int b) :x(a), y(b) { cout << "construct" << endl; }
    Point( /*不需要const*/Point& p) :x(p.x), y(p.y) { cout << "copy" << endl; }
};
Point fun(Point p)
{
    return p;
}
int main()
{
    Point a(1, 2);
    Point b=fun(a);
    return 0;
}

在這裏插入圖片描述
變成只調用一次複製構造函數了,怎麼回事?
先說移動構造函數:移動語義可以將資源(堆、系統對象等)通過淺拷貝方式從一個對象轉移到另一個對象,這樣能減少不必要的臨時對象的創建、拷貝以及銷燬,可以大幅度提高C++應用程序的性能,消除臨時對象的維護(創建和銷燬)對性能的影響。
在此處直接把形參的地址給了b,調的是移動構造函數。因此也不用const。
再推薦一篇講編譯器優化的博客:https://blog.csdn.net/qq_36482119/article/details/101039634
講移動構造函數的博客
https://blog.csdn.net/weiqing00/article/details/80929788

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章