簡體   English   中英

調用副本構造函數的邏輯

[英]logic of calling copy constructor

class base {
public:
    base(){
        cout << "base constructor" << endl;
    }
    base(const base& rh) {
        cout << "base copy constructor" << endl;
    }
};

//case 1:
class der : public base {
};

//case 2: 
class der : public base {
public:
    der(){
        cout << "der constructor" << endl;
    }
    der(const der& rh) {
        cout << "der copy constructor" << endl;
    }
};

int main() {
 der d;
 der d1(d);
}

情況1:der d1(d); 調用基類副本構造函數,而在

情況2,將調用基類的默認構造函數和der類的副本構造函數。

誰能解釋邏輯?

在情況1中,您將獲得由編譯器綜合的默認副本構造函數。 定義為復制基礎和成員。

在情況2中,您定義了自己的副本構造函數,該構造函數將執行您要執行的操作。 您沒有在基類的初始值設定項列表中放置任何內容,因此基數是默認構造的[*],與未顯式初始化基數的任何其他構造函數相同。 如果der有任何數據成員,則這些數據成員也不會被復制。

[*]或其他類型的初始化之一,對於非POD類來說,它們是相同的。 我永遠不記得那些細節。

默認情況下,派生副本構造函數不會調用基類副本構造函數本身。 當您不告訴派生類副本構造函數調用基類副本構造函數時,它仍然需要構造基類子對象,因此必須調用基類默認構造函數。

但是在下面的示例中,您將看到可以在派生類的成員初始化列表中顯式添加對基本副本構造函數的調用:

class base {
public:
    base(int i):m_i(i){
        cout << "base constructor" << endl;
    }
    base(const base& rh) {
        m_i = rh.m_i;
        cout << "base copy constructor" << endl;
    }
private:
int m_i;
};

//case 2: 
class der : public base {
public:
    der(int i,int j):base(i),m_j(j){
        cout << "der constructor" << endl;
    }
    der(const der& rh):base(rh) {
        m_j = rh.m_j;
        cout << "der copy constructor" << endl;
    }
private:
    int m_j;
};

int main() {
 der d(1,2);
 der d1(d); //d1.m_i = 1, d1.m_j = 2
}

//result
//base copy constructor
//der copy constructor

在第一種情況下,您沒有為der指定構造函數,因此編譯器會為您決定,即將d的數據分別復制到d1 ,在此過程中調用base復制構造函數。

在第二種情況下,您指定了復制構造函數,在這種情況下,您不會自己調用base的復制構造函數。 由於您已經覆蓋了der的副本構造函數(告訴編譯器按照您說的去做,而不是要執行的操作),因此編譯器無法假定您也打算調用base的副本構造函數。

基本上,有一個副本副本的調用。 因此,在case-2中,調用了der的copy-con,如果願意,可以在代碼中使用基數的copy-con。 在第一種情況下,由於您未實現copy-con,因此它將從其基址調用該函數,就像對僅在基類中實現的任何函數一樣。

暫無
暫無

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

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