建構函式,拷貝賦值函式的N種呼叫情況
一、
class Date
{
public:
Date()//建構函式
{
cout << "Date()" << endl;
}
Date(const Date& d)//拷貝構造
{
cout << "Date(const Date& d)" << endl;
}
Date& operator=(const Date& d)//賦值運算子過載
{
cout << "Date& operator=(const Date& d)" << endl;
return *this;
}
~Date()//解構函式
{
cout << "~Date()" << endl;
}
};
1.場景一
void fun1(Date d)
{}
int main()
{
Date d1;
fun1(d1);
system("pause");
return 0;
}
- Date d1;呼叫建構函式
- fun1(d1);d1值傳遞,要生成一個臨時變數,拷貝構造(傳值是拷貝構造)
- 倆次析構
2.場景二
void fun2(Date& d)
{}
int main()
{
Date d1;
fun2(d1);
system("pause");
return 0;
}
- Date d1;呼叫建構函式
- fun2(d1);傳的是d1的引用,引用相當於別名,不建立臨時變數,所以這裡宣告當不呼叫
- 一次析構
3.場景三
Date fun3()
{
Date d;
return d;
}
int main()
{
Date d2=fun3();
system("pause");
return 0;
}
- 呼叫fun3(),Date d;呼叫一次建構函式
- Date d2 = fun3();return d;返回一個臨時變數,這時也要進行一次拷貝構造
- Date d2 = fun3();呼叫一次拷貝構造
- 編譯器會自動優化,將上述倆次拷貝構造合併成一次(在同一表示式中)
- 倆次析構
所以一共是,一次構造,一次拷貝構造,倆次析構
4.場景四:
Date& fun4()
{
Date d;
return d;
}
int main()
{
Date d2=fun4();
system("pause");
return 0;
}
- Date d;構造
- Date d2=fun4();析構,fun4()形參一個匿名物件,匿名物件只在這行用以下,馬上析構
- 拷貝構造d2
- 析構
5.場景五:
Date fun5()
{
return Date();
}
int main()
{
Date d3;
d3 = fun5();
system("pause");
return 0;
}
- Date d3:構造
- fun5():函式內進行一次構造
- d3 = fun5:賦值運算子過載
- 倆次析構
6.場景六:
Date& fun6()
{
return Date();
}
int main()
{
Date d3;
d3 = fun6();
system("pause");
return 0;
}
- Date d3:構造
- fun6():函式內進行一次構造
- fun6()函式返回值是引用,構造了一個匿名引數,立馬析構,呼叫一次析構
- d3 = fun6():賦值運算子過載
- 析構d3
二、
class AA
{
public:
AA()//建構函式
{
cout << "AA()" << endl;
}
AA(const AA& d)//拷貝構造
{
cout << "AA(const AA& d)" << endl;
}
AA& operator=(const AA& d)//賦值運算子過載
{
cout << "AA& operator=(const AA& d)" << endl;
return *this;
}
~AA()//解構函式
{
cout << "~AA()" << endl;
}
};
AA f(AA a)
{
return a;
}
1.場景一
void Test1()
{
AA a1;
a1 = f(a1);
}
- AA a1:構造
- f(a1):拷貝構造;傳值:拷貝構造,傳值過程不能優化
- return a;返回一個臨時變數拷貝構造
- a出了作用域即被銷燬,析構
- a1 = f(a1)賦值運算子過載
- 倆次析構
2.場景二:
void Test2()
{
AA a1;
AA a2 = f(a1);
}
- AA a1:構造
- f(a1):值傳遞,拷貝構造
- AA a2 = f(a1)拷貝構造,與函式AA的返回臨時變數(return a)拷貝構造,倆次合併成一次,在用一個表單式中,編譯器優化
- 三次析構
3.場景三:
void Test3()
{
AA a1;
AA a2 = f(f(a1));
}
- AA a1:構造
- f(a1):拷貝構造
- f(f(a1)):拷貝構造 ;與f(a1)的返回值一起優化為一次
- 一次析構
- a2 = f(f(a1)):拷貝構造,與f(f(a1))的返回值一起優化為一次
- 三次析構
相關文章
- C++中建構函式,拷貝建構函式和賦值函式的詳解C++函式賦值
- C++之Big Three:拷貝構造、拷貝賦值、解構函式探究C++賦值函式
- C++拷貝建構函式(深拷貝,淺拷貝)C++函式
- C++拷貝建構函式詳解C++函式
- 類的陣列初始化後會呼叫拷貝建構函式陣列函式
- c/c++ 拷貝控制 建構函式的問題C++函式
- 建構函式之間的呼叫函式
- 預設建構函式、引數化建構函式、複製建構函式、解構函式函式
- 類的建構函式和解構函式函式
- JavaScript函式引數解構賦值JavaScript函式賦值
- C++建構函式和解構函式呼叫虛擬函式時使用靜態聯編C++函式
- 建構函式與解構函式函式
- 沒有返回值的建構函式是怎麼完成賦值的?函式賦值
- 結構體中的指標&&複製賦值建構函式改造結構體指標賦值函式
- c++中使用建構函式初始化列表的情況C++函式
- 預設建構函式和帶預設值的建構函式不能同時存在函式
- C++ 建構函式和解構函式C++函式
- 你不知道的JavaScript--Item8 函式,方法,建構函式呼叫JavaScript函式
- ## 建構函式函式
- 函式組合的 N 種模式函式模式
- C++ 禁用類的複製建構函式和賦值運算子C++函式賦值
- 1:賦值運算子函式賦值函式
- C++:建構函式的分類和呼叫C++函式
- 建構函式與普通函式的區別函式
- 關於建構函式與解構函式的分享函式
- 賦值、淺拷貝與深拷貝賦值
- JS的五種函式呼叫方式JS函式
- PHP筆記:建構函式與解構函式PHP筆記函式
- JavaScript 建構函式JavaScript函式
- 第 8 節:函式-函式巢狀呼叫與返回值函式巢狀
- 建構函式的prototype與各種繼承函式繼承
- 【譯】JavaScript 工廠函式 vs 建構函式JavaScript函式
- Solidity語言學習筆記————23、函式呼叫和賦值Solid筆記函式賦值
- C++入門記-建構函式和解構函式C++函式
- 【C++】初始化列表建構函式VS普通建構函式C++函式
- 【Python】直接賦值,深拷貝和淺拷貝Python賦值
- 高階函式與標籤函式,解構賦值與物件字面量的簡化學習函式賦值物件
- 建構函式和類函式