建構式
- 構造和析構概念語法
- 建構式的分類
- 有參建構式3種呼叫方法
- 拷貝建構式4種呼叫時機
- 場景1和2:A a(b); A a = b;
- 場景3:形參是一個元素,實參傳遞給形參
- 場景4:函式回傳值回傳一個元素,匿名物件
- 匿名物件的去和留
- 物件的初始化 和 物件的=操作 是兩個不同的概念
- 構造和析構
- 構造和析構概念語法
- 建構式的分類
- 有參建構式3種呼叫方法
- 拷貝建構式4種呼叫時機
- 場景1和2:A a(b); A a = b;
- 場景3:形參是一個元素,實參傳遞給形參
- 場景4:函式回傳值回傳一個元素,匿名物件
- 匿名物件的去和留
- 物件的初始化 和 物件的=操作 是兩個不同的概念
- 建構式呼叫規則研究(寫了建構式則必須呼叫)
- 多個物件的構造 建構式初始化串列
- 建構式和解構式的呼叫順序(先組合物件的構造、自己構造;析構和構造相反)
- 深拷貝和淺拷貝
- 問題拋出 顯示的撰寫拷貝建構式
- 默認的=號操作 也是淺拷貝,解決方案多載=運算子
- 總結:C++編譯給提供的默認的拷貝構造和=操作都是淺拷貝
- 構造和析構綜合練習
- 匿名物件:直接呼叫建構式
- 匿名物件:構造中呼叫構造
- 建構式呼叫規則研究(寫了建構式則必須呼叫)
- 多個物件的構造 建構式初始化串列
- 建構式和解構式的呼叫順序(先組合物件的構造、自己構造;析構和構造相反)
- 深拷貝和淺拷貝
- 問題拋出 顯示的撰寫拷貝建構式
- 默認的=號操作 也是淺拷貝,解決方案多載=運算子
- 總結:C++編譯給提供的默認的拷貝構造和=操作都是淺拷貝
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string.h>
using namespace std;
class Test
{
public:
#if 0
void init(int x, int y)
{
m_x = x;
m_y = y;
}
#endif
//test類的建構式
//在物件被創建的時候,用來初始化物件的函式
Test()//無引數的建構式
{
m_x = 0;
m_y = 0;
}
Test(int x, int y)
{
m_x = x;
m_y = y;
// name = (char*)malloc(100);
strcpy(name, "zhang3");
}
Test(int x)
{
m_x = x;
m_y = 0;
}
void printT()
{
cout << "x = " << m_x << " y = " << m_y << endl;
}
//解構式和建構式都沒有回傳值,
//解構式沒有形參
~Test() {
cout << "~Test()...." << endl;
if (name != NULL) {
// free(name);
cout << "free succ!" << endl;
}
}
private:
int m_x;
int m_y;
char *name;
};
void test1()
{
Test t1(10, 20);
t1.printT();
//在一個物件臨死之前,要自定呼叫解構式
}
int main(void)
{
#if 0
Test t1(10, 20);
t1.printT();
//t1.init(10, 20);
Test t2(100);
t2.printT();
Test t3;//就是呼叫類的無引數建構式
t3.printT();
#endif
test1();
return 0;
}
拷貝建構式
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Test
{
public:
Test()
{
m_x = 0;
m_y = 0;
}
Test(int x, int y)
{
m_x = x;
m_y = y;
}
void printT()
{
cout << "x =" << m_x << ", y = " << m_y << endl;
}
#if 1
//顯示的拷貝建構式
Test(const Test &another)
{
cout << "Test(const Test &)..." << endl;
m_x = another.m_x;
m_y = another.m_y;
}
#endif
#if 0
//? 會有一個默認的拷貝建構式
Test(const Test &another)
{
m_x = another.m_x;
m_y = another.m_y;
}
#endif
//=賦值運算子
void operator=(const Test &another)
{
m_x = another.m_x;
m_y = another.m_y;
}
private:
int m_x;
int m_y;
};
int main(void)
{
Test t1(100, 200);
Test t2(t1);
t2.printT();
//建構式是物件初始化的時候呼叫
Test t3; //依然是初始化t3的時候呼叫t3建構式,依然是呼叫t3的拷貝建構式
t3 = t1; //呼叫的不是t3拷貝建構式,而是t3的賦值運算子函式
return 0;
}
默認的建構式和決議建構式
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Test
{
public:
//默認的無參建構式
#if 0
Test()
{
}
#endif
//顯示提供一個有引數的建構式,默認的建構式就不復存在
Test(int x, int y)
{
m_x = x;
m_y = y;
}
Test() {
m_x = 0;
m_y = 0;
}
void printT()
{
cout << "x = " << m_x << " y = " << m_y << endl;
}
//默認的解構式
#if 0
~Test()
{
}
#endif
~Test() {
cout << "~Test()..." << endl;
}
private:
int m_x;
int m_y;
};
int main(void)
{
Test t1;//呼叫Test無參構造
t1.printT();
return 0;
}
默認的拷貝建構式
- 類中 會有個默認的無參建構式:
當沒有任何顯示的建構式(顯示的無參構,顯示有參,顯示拷貝構造) 的時候,默認無參建構式就會出現,
-
會有默認的拷貝建構式:
-->當沒有 **顯示的拷貝構造 *** 的函式,默認的拷貝構造就會出現, -
會有默認的解構式
--> 當沒有顯示的解構式的時候, 默認的解構式就會出現
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class A
{
public:
#if 0
A()
{
}
#endif
#if 0
A(const A &another)
{
m_a = another.m_a;
m_b = another.m_b;
}
#endif
A()
{
}
A(int a, int b)
{
}
#if 0
~A()
{
}
#endif
~A()
{
cout << "~A()" << endl;
}
private:
int m_a;
int m_b;
};
//類中 會有個默認的無參建構式: 、
// -->當沒有任何***顯示的建構式(顯示的無參構,顯示有參,顯示拷貝構造)*** 的時候,默認無參建構式就會出現,
// 會有默認的拷貝建構式:
// -->當沒有 **顯示的拷貝構造 *** 的函式,默認的拷貝構造就會出現,
// 會有默認的解構式
// --> 當沒有***顯示的解構式***的時候, 默認的解構式就會出現,
int main(void)
{
A a;
A a1(a);
return 0;
}
拷貝建構式的應用場景
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Test
{
public:
Test()
{
cout << "test()..." << endl;
m_x = 0;
m_y = 0;
}
Test(int x, int y)
{
cout << "Test(int x, int y)..." << endl;
m_x = x;
m_y = y;
}
Test(const Test & another)
{
cout << "Test(const Test &)..." << endl;
m_x = another.m_x;
m_y = another.m_y;
}
void operator=(const Test &another)
{
cout << "operatoer = (const Test &)" << endl;
m_x = another.m_x;
m_y = another.m_y;
}
void printT() {
cout << "x = " << m_x << ", m_y = " << m_y << endl;
}
~Test() {
cout << "~Test()..." << endl;
}
private:
int m_x;
int m_y;
};
//解構式呼叫的順序, 跟構造相反, 誰先構造的,誰后析構,
//場景1
void test1()
{
Test t1(10, 20);
Test t2(t1);//Test t2 = t1;
}
//場景2
void test2()
{
Test t1(10, 20);
Test t2;
t2 = t1;//=運算子
}
void func(Test t)//Test t = t1; //Test t 的拷貝建構式
{
cout << "func begin..." << endl;
t.printT();
cout << "func end..." << endl;
}
//場景3
void test3()
{
cout << "test3 begin..." << endl;
Test t1(10, 20);
func(t1);
cout << "test3 end..." << endl;
}
//場景4
Test func2()
{
cout << "func2 begin..." << endl;
Test temp(10, 20);
temp.printT();
cout << "func2 end..." << endl;
return temp;
}//匿名的物件 = temp 匿名物件.拷貝構造(temp)
void test4()
{
cout << "test4 being.. " << endl;
func2();// 回傳一個匿名物件, 當一個函式回傳一個匿名物件的時候,函式外部沒有任何
//變數去接收它, 這個匿名物件將不會再被使用,(找不到), 編譯會直接將個這個匿名物件
//回收掉,而不是等待整改函式執行完畢再回收.
//匿名物件就被回收,
cout << "test4 end" << endl;
}
void test5()
{
cout << "test 5begin.. " << endl;
Test t1 = func2(); //會不會觸發t1拷貝構造來 t1.拷貝(匿名)?
//并不會觸發t1拷貝,而是 將匿名物件轉正 t1,
//把這個匿名物件 起了名字就叫t1.
cout << "test 5 end.." << endl;
}
//場景6
void test6()
{
cout << "test6 begin..." << endl;
Test t1;//t1已經被初始化了,
t1 = func2(); //t1已經被初始化了,所以func2回傳的匿名物件不會再次轉正,而依然是匿名物件,
//所以t1會呼叫等號運算子,t1.operator=(匿名物件), 然后編譯器會立刻回收掉匿名物件
t1.printT();
cout << "test6 end.." << endl;
}
int main(void)
{
//test1();
//test2();
//test3();
//test4();
//test5();
test6();
return 0;
}
深拷貝和淺拷貝
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Test
{
public:
Test()
{
cout << "test()..." << endl;
m_x = 0;
m_y = 0;
}
Test(int x, int y)
{
cout << "Test(int x, int y)..." << endl;
m_x = x;
m_y = y;
}
Test(const Test & another)
{
cout << "Test(const Test &)..." << endl;
m_x = another.m_x;
m_y = another.m_y;
}
void operator=(const Test &another)
{
cout << "operatoer = (const Test &)" << endl;
m_x = another.m_x;
m_y = another.m_y;
}
void printT() {
cout << "x = " << m_x << ", m_y = " << m_y << endl;
}
~Test() {
cout << "~Test()..." << endl;
}
private:
int m_x;
int m_y;
};
//解構式呼叫的順序, 跟構造相反, 誰先構造的,誰后析構,
//場景1
void test1()
{
Test t1(10, 20);
Test t2(t1);//Test t2 = t1;
}
//場景2
void test2()
{
Test t1(10, 20);
Test t2;
t2 = t1;//=運算子
}
void func(Test t)//Test t = t1; //Test t 的拷貝建構式
{
cout << "func begin..." << endl;
t.printT();
cout << "func end..." << endl;
}
//場景3
void test3()
{
cout << "test3 begin..." << endl;
Test t1(10, 20);
func(t1);
cout << "test3 end..." << endl;
}
//場景4
Test func2()
{
cout << "func2 begin..." << endl;
Test temp(10, 20);
temp.printT();
cout << "func2 end..." << endl;
return temp;
}//匿名的物件 = temp 匿名物件.拷貝構造(temp)
void test4()
{
cout << "test4 being.. " << endl;
func2();// 回傳一個匿名物件, 當一個函式回傳一個匿名物件的時候,函式外部沒有任何
//變數去接收它, 這個匿名物件將不會再被使用,(找不到), 編譯會直接將個這個匿名物件
//回收掉,而不是等待整改函式執行完畢再回收.
//匿名物件就被回收,
cout << "test4 end" << endl;
}
void test5()
{
cout << "test 5begin.. " << endl;
Test t1 = func2(); //會不會觸發t1拷貝構造來 t1.拷貝(匿名)?
//并不會觸發t1拷貝,而是 將匿名物件轉正 t1,
//把這個匿名物件 起了名字就叫t1.
cout << "test 5 end.." << endl;
}
//場景6
void test6()
{
cout << "test6 begin..." << endl;
Test t1;//t1已經被初始化了,
t1 = func2(); //t1已經被初始化了,所以func2回傳的匿名物件不會再次轉正,而依然是匿名物件,
//所以t1會呼叫等號運算子,t1.operator=(匿名物件), 然后編譯器會立刻回收掉匿名物件
t1.printT();
cout << "test6 end.." << endl;
}
int main(void)
{
//test1();
//test2();
//test3();
//test4();
//test5();
test6();
return 0;
}
建構式的初始化串列
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Test
{
public:
Test()
{
cout << "test()..." << endl;
m_x = 0;
m_y = 0;
}
Test(int x, int y)
{
cout << "Test(int x, int y)..." << endl;
m_x = x;
m_y = y;
}
Test(const Test & another)
{
cout << "Test(const Test &)..." << endl;
m_x = another.m_x;
m_y = another.m_y;
}
void operator=(const Test &another)
{
cout << "operatoer = (const Test &)" << endl;
m_x = another.m_x;
m_y = another.m_y;
}
void printT() {
cout << "x = " << m_x << ", m_y = " << m_y << endl;
}
~Test() {
cout << "~Test()..." << endl;
}
private:
int m_x;
int m_y;
};
//解構式呼叫的順序, 跟構造相反, 誰先構造的,誰后析構,
//場景1
void test1()
{
Test t1(10, 20);
Test t2(t1);//Test t2 = t1;
}
//場景2
void test2()
{
Test t1(10, 20);
Test t2;
t2 = t1;//=運算子
}
void func(Test t)//Test t = t1; //Test t 的拷貝建構式
{
cout << "func begin..." << endl;
t.printT();
cout << "func end..." << endl;
}
//場景3
void test3()
{
cout << "test3 begin..." << endl;
Test t1(10, 20);
func(t1);
cout << "test3 end..." << endl;
}
//場景4
Test func2()
{
cout << "func2 begin..." << endl;
Test temp(10, 20);
temp.printT();
cout << "func2 end..." << endl;
return temp;
}//匿名的物件 = temp 匿名物件.拷貝構造(temp)
void test4()
{
cout << "test4 being.. " << endl;
func2();// 回傳一個匿名物件, 當一個函式回傳一個匿名物件的時候,函式外部沒有任何
//變數去接收它, 這個匿名物件將不會再被使用,(找不到), 編譯會直接將個這個匿名物件
//回收掉,而不是等待整改函式執行完畢再回收.
//匿名物件就被回收,
cout << "test4 end" << endl;
}
void test5()
{
cout << "test 5begin.. " << endl;
Test t1 = func2(); //會不會觸發t1拷貝構造來 t1.拷貝(匿名)?
//并不會觸發t1拷貝,而是 將匿名物件轉正 t1,
//把這個匿名物件 起了名字就叫t1.
cout << "test 5 end.." << endl;
}
//場景6
void test6()
{
cout << "test6 begin..." << endl;
Test t1;//t1已經被初始化了,
t1 = func2(); //t1已經被初始化了,所以func2回傳的匿名物件不會再次轉正,而依然是匿名物件,
//所以t1會呼叫等號運算子,t1.operator=(匿名物件), 然后編譯器會立刻回收掉匿名物件
t1.printT();
cout << "test6 end.." << endl;
}
int main(void)
{
//test1();
//test2();
//test3();
//test4();
//test5();
test6();
return 0;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/79214.html
標籤:C++
