C++之类与对象(2)
接著上一節(jié),今天講C++中類的構(gòu)造函數(shù)與析構(gòu)函數(shù),對象的賦值與復(fù)制.
1.用過C#語言的人,都知道構(gòu)造函數(shù)是一種特殊的成員函數(shù),它主要用于對對象分配空間,進行初始化。構(gòu)造函數(shù)的名字必須與類名相同。可以有任何類型的參數(shù),但不返回任何值,是在建立對象時自動執(zhí)行的。和上一節(jié)一樣,還是用Kid類來說明。
1 class Kid2 {
3 private:
4 int age;
5 char*name;
6 char*sex;
7 public:
8 Kid(int age,char*name,char*sex);
9 void showKid();
10 };
11
12 Kid::Kid(int age,char*name,char*sex)
13 {
14 Kid::age=age;
15 Kid::name=name;
16 Kid::sex=sex;
17 }
18
19 void Kid::showKid()
20 {
21 cout<<"姓名:"<<name<<endl<<"年齡:"<<age<<endl<<"性別:"<<sex<<endl;
22 }
接下來,建立對象并初始化:Kid kid(10,"rookie_j","男");另外一種使用new運算符動態(tài)建立對象:Kid *ptr=new Kid(10,"rookie_j","男");通過指針變量ptr來訪問:ptr->showKid();當(dāng)我們用new建立對象時,當(dāng)不再使用它時,要用delete運算符釋放它:delete ptr;和不同成員函數(shù)一樣,如果構(gòu)造函數(shù)定義在類體內(nèi)部,則作為內(nèi)聯(lián)函數(shù)處理;
在聲明類時,對數(shù)據(jù)成員的初始化一般在構(gòu)造函數(shù)中用賦值語句進行,但C++還提供了另外一種初始化數(shù)據(jù)成員的方法——用成員初始化表來實現(xiàn)對數(shù)據(jù)成員的初始化。它的一般形式為:類名::構(gòu)造函數(shù)名([參數(shù)表]):[(成員初始化表)];成員初始化表的形式為:成員名1(初始值1),成員名2(初始值2),成員名2(初始值2);比如:
Kid::Kid(int age,char *name,char *sex):age(age),name(name),sex(sex){};
接下來講一下析構(gòu)函數(shù):在我第一次在C++里看到這個名詞時,感覺這個知識點很深奧,結(jié)果看了以后,其實很簡單。它的作用和構(gòu)造函數(shù)剛好相反,用于撤銷對象,如:釋放分配給對象的內(nèi)存空間。析構(gòu)函數(shù)和構(gòu)造函數(shù)名相同,但在其前面要加~符號,析構(gòu)函數(shù)沒有參數(shù),也沒有返回值,且不能重載,因此一個類中只有一個析構(gòu)函數(shù)。以下三種情況,當(dāng)對象的生命周期結(jié)束時,析構(gòu)函數(shù)會被自動調(diào)用:(1)定義了全局對象,則在程序流程離開其作用域(如:main函數(shù)結(jié)束或調(diào)用Exit)時,調(diào)用該全局對象的析構(gòu)函數(shù);(2)對象被定義在函數(shù)體里,則當(dāng)這個函數(shù)執(zhí)行完后,該對象釋放,析構(gòu)函數(shù)被自動調(diào)用;(3)若一個對象使用new運算符動態(tài)創(chuàng)建的,在使用delete運算符釋放它時,會自動調(diào)用析構(gòu)函數(shù);
View Code 1 #include "stdafx.h"2 #include <iostream>
3
4 usingnamespace std;
5
6 class Kid
7 {
8 private:
9 int age;
10 char*name;
11 char*sex;
12 public:
13 Kid(int age,char*name,char*sex);
14 ~Kid();
15 void showKid();
16 };
17
18
19 Kid::Kid(int age,char*name,char*sex)
20 {
21 Kid::age=age;
22 Kid::name=newchar[strlen(name)];
23 strcpy(Kid::name,name);
24 Kid::sex=newchar[strlen(sex)];
25 strcpy(Kid::sex,sex);
26 }
27
28 Kid::~Kid()
29 {
30 cout<<"dispose object kid"<<endl;
31 delete []name;
32 delete []sex;
33 }
34
35 void Kid::showKid()
36 {
37 cout<<"姓名:"<<name<<endl<<"年齡:"<<age<<endl<<"性別:"<<sex<<endl;
38 }
39
40
41 int main()
42 {
43 Kid kid(10,"rookie_j","男");
44 kid.showKid();
45
46 Kid *ptr=new Kid(10,"rookie_x","女");
47 ptr->showKid();
48
49 delete ptr;
50
51 return0;
52 }
結(jié)果:
如果沒有給類定義構(gòu)造函數(shù),則編譯系統(tǒng)自動地生成一個默認(rèn)的構(gòu)造函數(shù),比如在Kid類中編譯系統(tǒng)會為其產(chǎn)生一個Kid::Kid(){};構(gòu)造函數(shù),這個默認(rèn)的構(gòu)造函數(shù)只能給對象開辟存儲空間,不能給數(shù)據(jù)成員賦值,這時數(shù)據(jù)成員的初值就是隨機數(shù)。對沒有定義構(gòu)造函數(shù)的類,其公有數(shù)據(jù)成員可以用初始化值表進行初始化,如:
1 class Kid2 {
3 public:
4 int age;
5 char*name;
6 char*sex;
7 };
8
9 int main()
10 {
11
12 Kid kid={10,"Rookie_j","男"};
13 cout<<"姓名:"<<kid.name<<endl<<"年齡:"<<kid.age<<endl<<"性別:"<<kid.sex<<endl;
14
15 return0;
16 }
但只要一個類定義了構(gòu)造函數(shù),系統(tǒng)將不再給它提供默認(rèn)構(gòu)造函數(shù);另外還有默認(rèn)的析構(gòu)函數(shù)(Kid::~Kid(){}),一般來說默認(rèn)的析構(gòu)函數(shù)就能滿足要求,但對一些需要做一些內(nèi)部處理的則應(yīng)該顯式定義析構(gòu)函數(shù)。帶默認(rèn)參數(shù)的構(gòu)造函數(shù)和之前所說的帶參數(shù)的成員函數(shù)是一樣的,對于構(gòu)造函數(shù)的重載,在這里我就不多說了,只想強調(diào)一點,如果是無參的構(gòu)造函數(shù)創(chuàng)建對象,應(yīng)該使用"類名 對象名"的形式,而不是"類名 對象名()";
2.對象的賦值其實和變量的賦值差不多,也是用賦值運算符=進行的,只不過進行賦值的兩個對象的類型必須相同,對象之間的賦值只是數(shù)據(jù)成員的賦值,而不對成員函數(shù)賦值;
?
View Code 1 #include "stdafx.h"2 #include <iostream>
3
4 usingnamespace std;
5
6 class Kid
7 {
8 private:
9 int age;
10 char*name;
11 char*sex;
12 public:
13 Kid(int age,char*name,char*sex);
14 Kid(){ };
15 ~Kid();
16 void showKid();
17 };
18
19
20 Kid::Kid(int age,char*name,char*sex)
21 {
22 Kid::age=age;
23 Kid::name=newchar[strlen(name)];
24 strcpy(Kid::name,name);
25 Kid::sex=newchar[strlen(sex)];
26 strcpy(Kid::sex,sex);
27 }
28
29 Kid::~Kid()
30 {
31 cout<<"dispose object kid"<<endl;
32 delete []name;
33 delete []sex;
34 }
35
36 void Kid::showKid()
37 {
38 cout<<"姓名:"<<name<<endl<<"年齡:"<<age<<endl<<"性別:"<<sex<<endl;
39 }
40
41 int main()
42 {
43 Kid kid(10,"rookie_j","男"),kid2;
44 kid.showKid();
45
46 kid2=kid;
47 kid2.showKid();
48
49 return0;
50 }
?
結(jié)果:
拷貝構(gòu)造函數(shù)是一種特殊的構(gòu)造函數(shù),其形參是類對象的引用。它主要用于在建立一個新的對象時,使用已經(jīng)存在的對象去初始化這個新對象。拷貝構(gòu)造函數(shù)也是構(gòu)造函數(shù),所以函數(shù)名必須與類名相同,參數(shù)只有一個就是同類對象的引用,每個類必須要有一個拷貝構(gòu)造函數(shù)。如果程序員自己不定義拷貝構(gòu)造函數(shù),系統(tǒng)會自動產(chǎn)生一個默認(rèn)拷貝構(gòu)造函數(shù)。調(diào)用拷貝構(gòu)造函數(shù)的形式有代入法:類名 對象2(對象1)和賦值法:類名 對象2=對象1;
View Code 1 #include "stdafx.h"2 #include <iostream>
3
4 usingnamespace std;
5
6 class Kid
7 {
8 private:
9 int age;
10 char*name;
11 char*sex;
12 public:
13 Kid(int age,char*name,char*sex);
14 Kid(const Kid &kid);
15 ~Kid();
16 void showKid();
17 };
18
19
20 Kid::Kid(int age,char*name,char*sex)
21 {
22 Kid::age=age;
23 Kid::name=newchar[strlen(name)];
24 strcpy(Kid::name,name);
25 Kid::sex=newchar[strlen(sex)];
26 strcpy(Kid::sex,sex);
27 }
28
29 Kid::Kid(const Kid &kid)
30 {
31 Kid::age=kid.age*2;
32 Kid::name=newchar[strlen(kid.name)];
33 strcpy(Kid::name,kid.name);
34 Kid::sex=newchar[strlen(kid.sex)];
35 strcpy(Kid::sex,kid.sex);
36 }
37
38 Kid::~Kid()
39 {
40 cout<<"dispose object kid"<<endl;
41 delete []name;
42 delete []sex;
43 }
44
45 void Kid::showKid()
46 {
47 cout<<"姓名:"<<name<<endl<<"年齡:"<<age<<endl<<"性別:"<<sex<<endl;
48 }
49
50 int main()
51 {
52 Kid kid(10,"rookie_j","男");
53 kid.showKid();
54
55 Kid kid2(kid);
56 kid2.showKid();
57
58 Kid kid3=kid2;
59 kid3.showKid();
60
61 return0;
62 }
結(jié)果:
?
同樣的默認(rèn)的拷貝構(gòu)造函數(shù):復(fù)制出與源對象的數(shù)據(jù)成員的值一樣的新對象。調(diào)用拷貝構(gòu)造函數(shù)的3種情況:(1)Kid kid2(kid1)或Kid kid2=kid1;(2)函數(shù)的形參是類的對象:fun(Kid kid){kid.showKid();}; int main(){Kid kid(10,"Rookie_j","男");fun(kid);return 0;};(3)函數(shù)返回值為類的對象:Kid fun(){Kid kid(10,"Rookie_j","男"); return kid;} int main(){ Kid kid; kid=fun();kid.showKid();return 0;};
3.最后還是一樣用一個實例來總結(jié)一下今天所說的內(nèi)容(開發(fā)工具:vs2010):
View Code 1 #include "stdafx.h"2 #include <iostream>
3
4 usingnamespace std;
5
6 class Kid
7 {
8 private:
9 int age;
10 char*name;
11 char*sex;
12 public:
13 Kid(int age,char*name,char*sex);
14 Kid(const Kid &kid); //自定義拷貝函數(shù)
15 ~Kid();
16 void showKid();
17 };
18
19
20 Kid::Kid(int age,char*name,char*sex)
21 {
22 Kid::age=age;
23 Kid::name=newchar[strlen(name)];
24 strcpy(Kid::name,name);
25 Kid::sex=newchar[strlen(sex)];
26 strcpy(Kid::sex,sex);
27 }
28
29 //Kid::Kid(int age,char *name,char *sex):age(age),name(name),sex(sex) //用成員初始化表對數(shù)據(jù)成員初始化
30 //{
31 //
32 //}
33
34 Kid::Kid(const Kid &kid)
35 {
36 Kid::age=kid.age*2;
37 Kid::name=newchar[strlen(kid.name)];
38 strcpy(Kid::name,kid.name);
39 Kid::sex=newchar[strlen(kid.sex)];
40 strcpy(Kid::sex,kid.sex);
41 }
42
43 Kid::~Kid() //自定義析構(gòu)函數(shù)
44 {
45 cout<<"dispose object kid"<<endl;
46 delete []name; //delete運算符釋放存儲空間
47 delete []sex;
48 }
49
50 void Kid::showKid()
51 {
52 cout<<"孩子:"<<endl<<"姓名:"<<name<<endl<<"年齡:"<<age<<endl<<"性別:"<<sex<<endl;
53 }
54
55 class Car
56 {
57 public:
58 char*no;
59 char*brand;
60 int speed;
61 void showCar();
62 ~Car(){};//仿默認(rèn)析構(gòu)
63 };
64
65
66
67 void Car::showCar()
68 {
69 cout<<"汽車:"<<endl<<"號碼:"<<no<<endl<<"品牌:"<<brand<<endl<<"速度:"<<speed<<"km/h"<<endl;
70 }
71
72 int main()
73 {
74 Kid kid(10,"rookie_j","男");
75 kid.showKid();
76
77 cout<<"--------------------"<<endl;
78
79 Kid kid2(kid); //代入法調(diào)用拷貝構(gòu)造函數(shù)
80 kid2.showKid();
81
82 cout<<"--------------------"<<endl;
83
84 Kid kid3=kid2; //賦值法調(diào)用拷貝構(gòu)造函數(shù)
85 kid3.showKid();
86
87 cout<<"--------------------"<<endl;
88
89 Kid *ptr=new Kid(10,"rookie_x","女"); //使用new運算符動態(tài)創(chuàng)建對象
90 ptr->showKid();
91
92 cout<<"--------------------"<<endl;
93
94 //delete ptr; //釋放對象所占的存儲空間
95
96 Car car={"8888888","Benz",200},car2;//只有沒定義構(gòu)造函數(shù)的類,才能用初始值表初始化公有數(shù)據(jù)成員,默認(rèn)構(gòu)造
97 car.showCar();
98
99
100 cout<<"--------------------"<<endl;
101
102 car2=car;//默認(rèn)拷貝構(gòu)造函數(shù)或car2(car)
103 car2.showCar();
104
105 cout<<"--------------------"<<endl;
106
107 return0;
108 }
結(jié)果:
但在運行的時候,發(fā)現(xiàn)一個問題如果把delete ptr; 這句的注釋去掉,結(jié)果汽車的情況就顯示不出來了;
結(jié)果:
不知道為什么?求助各位大俠!
轉(zhuǎn)載于:https://www.cnblogs.com/CaiNiaoZJ/archive/2011/07/24/2115041.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的C++之类与对象(2)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mongodb和SQL语句对应查找表
- 下一篇: VCS使用指令