建構函式,拷貝賦值函式的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++拷貝建構函式(深拷貝,淺拷貝)C++函式
- 拷貝建構函式中的陷阱函式
- C++之Big Three:拷貝構造、拷貝賦值、解構函式探究C++賦值函式
- 拷貝建構函式(比較全的)函式
- C++語言之結構體、類、建構函式、拷貝建構函式C++結構體函式
- C++拷貝建構函式詳解C++函式
- C++ 拷貝建構函式詳解C++函式
- 類的陣列初始化後會呼叫拷貝建構函式陣列函式
- C++複製控制:拷貝建構函式C++函式
- c/c++ 拷貝控制 建構函式的問題C++函式
- C++/CLI思辨錄之拷貝建構函式C++函式
- 第五篇:明確拒絕不想編譯器自動生成的拷貝建構函式和賦值運算子過載函式編譯函式賦值
- c# tcbs之建構函式呼叫建構函式示例C#函式
- [C++]顯示呼叫建構函式和解構函式C++函式
- 建構函式之間的呼叫函式
- C++的一點基本自我修養(二)--拷貝建構函式C++函式
- 《高質量C++/C程式設計指南》第9章:類的建構函式、解構函式與賦值函式C++C程式程式設計函式賦值
- 批註:C++中複製建構函式與過載賦值操作符總結:預設淺拷貝,帶指標的需要深拷貝C++函式賦值指標
- JavaScript函式引數解構賦值JavaScript函式賦值
- 預設建構函式、引數化建構函式、複製建構函式、解構函式函式
- Java的預設建構函式呼叫Java函式
- 類的建構函式和解構函式函式
- 高質量C++/C程式設計指南(第9章 類的建構函式、解構函式與賦值函式) (轉)C++C程式程式設計函式賦值
- 沒有返回值的建構函式是怎麼完成賦值的?函式賦值
- 結構體中的指標&&複製賦值建構函式改造結構體指標賦值函式
- c++中使用建構函式初始化列表的情況C++函式
- C語言實現字串拷貝函式的幾種方法C語言字串函式
- javascript建構函式的返回值JavaScript函式
- 建構函式與解構函式函式
- 帶複製建構函式、賦值運算子的模板佇列函式賦值佇列
- C++建構函式和解構函式呼叫虛擬函式時使用靜態聯編C++函式
- 賦值、淺拷貝與深拷貝賦值
- Effective c++(筆記) 中關於建構函式、解構函式以及賦值操作符的知識C++筆記函式賦值
- C++ 建構函式和解構函式C++函式
- C++ 禁用類的複製建構函式和賦值運算子C++函式賦值