#include<iostream>
using namespace std;
class A{
public:
A(int n=10){cout<<"默認構造"<<endl;}
/*這里如果注釋掉了下邊的拷貝函式,運行程式的時候他會呼叫兩次解構式,只呼叫一次默認建構式,運行是在vs2019中,加了個斷點看著他把自己析構了兩次,把下邊的注釋調結果呼叫一次建構式,呼叫一次解構式,我把這個在網頁上找了個在線的編譯器運行了一下,不管注不注釋下面的拷貝函式結果都是呼叫一次建構式一次解構式,到這一頭霧水,我也沒搞懂那個add函式里傳的是什么意思,是照著老師出的題寫的,寫的不是很全,剩了些引數。
*/
A(const A& a){cout<<"拷貝"<<endl;}
~A(){cout<<"解構式"<<endl;}
};
void add(A a){}
int main()
{
add(A(10));
return 0;
}
uj5u.com熱心網友回復:
應該是實參和形參都呼叫了析構,而拷貝構造相當于是一個參考,add函式是一個空函式,只是定義了一個A物件的形參uj5u.com熱心網友回復:
沒搞明白拷貝函式那,加上只呼叫一次析構,不加調了兩次,建構式我加短點一步步走的時候只調了一次,我特意又換了兩個編譯器,結果一個和vs一樣,一個和我說的網頁上的一樣,這是不是跟編譯器有關。
uj5u.com熱心網友回復:
個人認為=========
若不對型別別(struct、class 或 union)提供任何用戶定義的復制建構式,則編譯器始侄訓宣告一個復制建構式,作為其類的非 explicit 的 inline public 成員。當以下各項均為真時,這個隱式宣告的復制建構式擁有形式 T::T(const T&):
T 的每個直接與虛基類 B 均擁有復制建構式,其形參為 const B& 或 const volatile B&;
T 的每個型別別或型別別陣列的非靜態資料成員 M 均擁有復制建構式,其形參為 const M& 或 const volatile M&。
否則,隱式宣告的復制建構式是 T::T(T&)。(注意因為這些規則,隱式宣告的復制建構式不能系結到 volatile 左值實參)。
================
以上摘自cpprefrence
試一下下列代碼
class B {
public:
B(){}
B(const B& ){}
};
class A {
B b1;
public:
A(int n = 10) { cout << "默認構造" << endl; }
/*這里如果注釋掉了下邊的拷貝函式,運行程式的時候他會呼叫兩次解構式,只呼叫一次默認建構式,運行是在vs2019中,加了個斷點看著他把自己析構了兩次,把下邊的注釋調結果呼叫一次建構式,呼叫一次解構式,我把這個在網頁上找了個在線的編譯器運行了一下,不管注不注釋下面的拷貝函式結果都是呼叫一次建構式一次解構式,到這一頭霧水,我也沒搞懂那個add函式里傳的是什么意思,是照著老師出的題寫的,寫的不是很全,剩了些引數。
*/
~A() {
cout << this << endl;
cout << "解構式" << endl;
}
};
void add(A a) {
}
int main()
{
add(A(10));
return 0;
}
uj5u.com熱心網友回復:
注意我貼的那一段,當你不提供建構式時,編譯器提供的建構式形式位T(T&) 不是T (const T&) 因為引數是T& 不能直接系結臨時變數所以要發生復制。而你提供了T(const & T) 會引起復制消除,具體看
https://zh.cppreference.com/w/cpp/language/copy_elision
因為給A加了一個欄位B,B具有T(const T&)形式的拷貝建構式,所以A的隱式拷貝構造將會是A(const A&)形式,
所以,會引起拷貝消除。
uj5u.com熱心網友回復:
有勞你費心了,謝謝。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/105769.html
標籤:C++ 語言
