C++ 構造函數與析構函數

構造函數與析構函數

OOP第二課

1、構造函數

1.1 構造函數具有一些特殊的性質

1.2 定義構造函數的一般形式

1.3 利用構造函數創(chuàng)建對象

2、成員初始化表

3、缺省參數的構造函數

4旧找、重載構造函數

5、拷貝構造函數

5.1 自定義拷貝構造函數

5.2 缺省的拷貝構造函數

5.3 調用拷貝構造函數的三種情況

5.4 淺拷貝和深拷貝

6麦牺、析構函數

7钮蛛、調用構造函數和析構函數的順序

8、對象的生存期

創(chuàng)一個小群剖膳,供大家學習交流聊天

如果有對學C++方面有什么疑惑問題的魏颓,或者有什么想說的想聊的大家可以一起交流學習一起進步呀。

也希望大家對學C++能夠持之以恒

C++愛好群吱晒,

如果你想要學好C++最好加入一個組織甸饱,這樣大家學習的話就比較方便,還能夠共同交流和分享資料,給你推薦一個學習的組織:快樂學習C++組織 可以點擊組織二字叹话,可以直達


構造函數和析構函數都是類的成員函數,但它們都是特殊的成員函數,執(zhí)行特殊的功能,不用調用便自動執(zhí)行,而且這些函數的名字與類的名字有關偷遗。

C++語言中有一些成員函數性質是特殊的,這些成員函數負責對象的建立驼壶、刪除氏豌。這些函數的特殊性在于可以由編譯器自動地隱含調用,其中一些函數調用格式采用運算符函數重載的語法热凹。

C++引進一個自動完成對象初始化過程的機制泵喘,這就是類的構造函數。

對象的初始化

1般妙、數據成員是不能在聲明類時初始化

2纪铺、類型對象的初始化方法:

1) 調用對外接口(public成員函數)實現(xiàn):聲明類→定義對象→調用接口給成員賦值

2) 應用構造函數(constructor) 實現(xiàn):聲明類→定義對象→同時給成員賦值

1、構造函數

構造函數是一種特殊的成員函數,它主要用于為對象分配空間,進行初始化碟渺。

1.1 構造函數具有一些特殊的性質:

(1) 構造函數的名字必須與類名相同霹陡。

(2) 構造函數可以有任意類型的參數,但不能指定返回類型。 它有隱含的返回值,該值由系統(tǒng)內部使用止状。

(3) 構造函數是特殊的成員函數,函數體可寫在類體內,也可寫在類體外。

(4) 構造函數可以重載,即一個類中可以定義多個參數個數或參數類型不同的構造函數攒霹。構造函數是不能繼承

(5) 構造函數被聲明為公有函數,但它不能像其他成員函數那樣被顯式地調用,它是在定義對象的同時被調用的怯疤。

(6) 在聲明類時如果沒有定義類的構造函數,編譯系統(tǒng)就會在編譯時自動生成一個默認形式的構造函數催束,

(7)?默認構造函數是構造對象時不提供參數的構造函數集峦。

(8) 除了無參數構造函數是默認構造函數外,帶有全部默認參數值的構造函數也是默認構造函數抠刺。

(9)?自動調用:構造函數在定義類對象時自動調用塔淤, 不需用戶調用,也不能被用戶調用速妖。在對象使用前調用高蜂。

(10)?調用順序:在對象進入其作用域時(對象使用前) 調用構造函數。

1.2 定義構造函數的一般形式

class類名

{

public:

類名(形參表)?;//構造函數的原型

//類的其它成員

};

類名::類名(形參表)//構造函數的實現(xiàn)

{

//函數體

}

1.3 利用構造函數創(chuàng)建對象

(1) 利用構造函數直接創(chuàng)建對象.其一般形式為:類名 對象名[(實參表)];

這里的“類名”與構造函數名相同,“實參表”是為構造函數提供的實際參數罕容。

例2.7 為類Date建立一個構造函數

#include<iostream.h>

classDate{

public:

Date(inty,intm,intd);//?構造函數

voidsetDate(inty,intm,intd);

voidshowDate();

private:

intyear,?month,?day;

};

Date::Date(inty,intm,intd)//?構造函數的實現(xiàn)

{?year=y;?month=m;?day=d;?}

voidDate::setDate(inty,intm,intd)

{?year=y;?month=m;?day=d;?}

inlinevoidDate::showDate()

{cout<

例2.8 利用構造函數直接創(chuàng)建對象

#include<iostream.h>

classDate{

//?省略备恤,?同例2.7

};

//?省略,?同例2.7

voidmain()

{

Datedate1(1998,4,28);//?定義類Date的對象date1,

//?自動調用date1的構造函數,初始化對象date1

cout<<"Date1?output1:"<

date1.showDate();//?調用date1的showDate(),顯示date1的數據

date1.SetDate(2002,11,14);//?調用date1的setDate(),

//?重新設置date1的數據

cout<<"Date1?output2:"<

date1.showDate();//?調用date1的showDate(),顯示date1的數據

}

constructing...

Date1output1:

1998.4.28

Date1output2:

2002.11.14

(2) 利用構造函數創(chuàng)建對象時,通過指針和new來實現(xiàn)锦秒。其一般語法形式為:

類名 *指針變量 = new 類名[(實參表)];

voidmain()

{

Date?*date1;

date1=newDate(1998,4,28);

//可合寫成:Date?*date1=new?Date(1998,4,28);

cout<<"Date1?output1:"<

date1->showDate();

date1->setDate(2002,11,14);

cout<<"Date1?output2:"<

date1->showDate();

deletedate1;

}

說明:

構造函數的名字必須與類名相同露泊,否則編譯器將把它當作一般的成員函數來處理。

構造函數是不能說明它的返回值類型的旅择,甚至說明為void類型也不行惭笑。

構造函數可以是不帶參數的。

classA{

public:

A();

//…

private:

intx;

};

A∷A()

{

cout<<"initialized?\n";

x=50;

}

main()

{

A?a;

}

有兩個長方柱,其長沉噩、寬捺宗、高分別為:(1)12,25,30;(2)15,30,21屁擅。求它們的體積偿凭。要求:編一個基于對象的程序,在類中用帶參數的構造函數派歌。

classBox{

public:

Box(int,int,int);

intvolume(?);

private:

intheight;

intwidth;

intlength;

};

Box::Box(inth,intw,intlen)

{

height?=?h;

width?=?w;

length?=?len;

}

intBox::volume(?)

{

returnheight*width*length;

}

intmain(?)

{

Boxbox1(12,25,30);

cout<<?box1.volume(?)?<

Boxbox2(15,30,21);

cout<<?box2.volume(?)?<

return0;

}

2弯囊、成員初始化表

對于常量類型和引用類型的數據成員,不能在構造函數中用賦值語句直接賦值,C++提供初始化表進行置初值。

帶有成員初始化表的構造函數的一般形式如下:

類名::構造函數名([參數表])[:(成員初始化表)]

{

// 構造函數體

}

成員初始化表的一般形式為:

數據成員名1(初始值1),數據成員名2(初始值2),……

例2.9 成員初始化表的使用

#include<iostream.h>

classA{

public:

A(intx1):x(x1),rx(x),pi(3.14)//?rx(x)相當于rx=x,?pi(3.14)相當于pi=3.14

{?}

voidprint()

{cout<<"x="<

private:

intx;int&?rx;constfloatpi;

};

main()

{

Aa(10);

a.print();

return0;

}

構造函數采用成員初始化表對數據成員進行初始化胶果,是一些程序員喜歡使用的方法匾嘱。

classB{

inti;

charj;

floatf;

public:

B(intI,charJ早抠,floatF)

{?i=I;?j=J;?f=F;?};

};

classB{

public:

B(intI,charJ,floatF):i(I),j(J),f(F)

{?}

private:

inti;

charj;

floatf;

};

說明

如果需要將數據成員存放在堆中或數組中霎烙,則應在構造函數中使用賦值語句,即使構造函數有成員初始化表也應如此蕊连。

classC{

public:

C(int?I,char?Ch,float?F,char?N[]):i(I),ch(Ch),f(F)

{?strcpy?(name,N);}

private:

inti;

charch;

floatf;

charname[25];

};

類成員是按照它們在類里被聲明的順序初始化的,與它們在初始化表中列出的順序無關悬垃。

【例2.10】

#include<iostream.h>

classD{

public:

D(inti):mem2(i),mem1(mem2+1)

{

cout<<"mem1:?"<

cout<<"mem2:?"<

}

private:

intmem1;

intmem2;

};

voidmain()

{

Dd(15);

}

mem1:?-858993459

mem2:?15

3、缺省參數的構造函數

例2.11

#include<iostream.h>

classCoord{

public:

Coord(inta=0,intb=0){?x=a;?y=b;}//?帶有缺省參數的構造函數

intgetx(){returnx;?}

intgety(){returny;?}

private:

intx,y;

};

voidmain()

{

Coordop1(5,6);Coordop2(5);?Coord?op3;

inti,j;

i=op1.getx();j=op1.gety();

cout<<"op1?i=?"<

i=op2.getx();j=op2.gety();

cout<<"op2?i=?"<

i=op3.getx();j=op3.gety();

cout<<"op3?i=?"<

}

classBox{

public:

Box(inth=10,intw=10,intl=10);//在聲明構造函數時指定默認參數

intvolume(?){return(height*width*length);?}

private:

intheight;

intwidth;

intlength;

};

Box::?Box(inth,intw,intl)//在定義函數時可以不指定默認參數

{

height=h;

width=w;

length=l;

}

4甘苍、重載構造函數

構造函數的重載

在一個類中可以定義多個構造函數尝蠕,以便對類對象提供不同的初始化的方法,供用戶選用载庭。這些構造函數具有相同的名字看彼,而參數的個數或參數的類

型不相同(這稱為構造函數的重載)

關于構造函數重載的說明

(1)?默認構造函數:一個調用構造函數時不必給出實參的構造函數。 顯然囚聚,無參的構造函數屬于默認構造函數靖榕。一個類只能有一個默認構造函數。

(2) 盡管在一個類中可以包含多個構造函數顽铸,但是對于每一個對象來說茁计,建立對象時只執(zhí)行其中一個構造函數,并非每個構造函數都被執(zhí)行跋破。

classBox{

public:

Box(inth,intw,intl):?height(h),width(w),length(l)?{?}

Box();

intvolume(?);

private:

intheight;

intwidth;

intlength;

};

Box::Box()

{

height?=10;

width?=10;

lenght?=10;

}

intBox::volume(?)

{

returnheight*width*length;

}

intmain(?)

{

Box?box1;//?書上為?box1();

cout<<?box1.volume(?)?<

Boxbox2(15,30,25);

cout<<?box2.volume(?)?<

return0;

}

例2.17 重載構造函數應用例程簸淀。

#include<iostream.h>

classDate{

public:

Date();//?無參數的構造函數

Date(inty,intm,intd);//?帶有參數的構造函數

voidshowDate();

private:

intyear,?month,?day;

};

Date::Date()

{?year=1998;?month=4;?day=28;?}

Date::Date(inty,intm,intd)

{?year=y;?month=m;?day=d;?}

inlinevoidDate::showDate()

{cout<

voidmain()

{

Date?date1;//?聲明類Date的對象date1,

//?調用無參數的構造函數

cout<<"Date1?output:?"<

date1.showDate();//?調用date1的showDate()毒返,顯示date1的數據

Datedate2(2002租幕,11,14);//?定義類Date的對象date2拧簸,

//?調用帶參數的構造函數

cout<<"Date2?output:?"<

date2.showDate();//?調用date2的showDate()交排,顯示date2的數據

}

運行結果:

Date1output:

1998.4.28

Date2output:

2002.11.14

例2.18 關于計時器的例子

#include<iostream.h>

#include<stdlib.h>

classtimer{

public:

timer()//?無參數構造函數,給seconds清0

{?seconds=0;?}

timer(char*?t)//?含一個數字串參數的構造函數

{?seconds=atoi(t);?}

timer(intt)//?含一個整型參數的構造函數

{?seconds=t;?}

timer(intmin,intsec)//?含兩個整型參數的構造函數

{?seconds=min*60+sec;?}

intgettime()

{returnseconds;?}

private:

intseconds;

};

main()

{

timer?a,b(10),c("20"),d(1,10);

cout<<"seconds1="<

cout<<"seconds2="<

cout<<"seconds3="<

cout<<"seconds4="<

return0;

}

classx{

public:

x();//?沒有參數的構造函數

x(inti=0);//?帶缺省參數的構造函數

};

//…

voidmain()

{

xone(10);//?正確,調用x(int?i=0)

x?two;//?存在二義性

//…

}

5透乾、拷貝構造函數

拷貝構造函數是一種特殊的構造函數,其形參是本類對象的引用步淹。其作用是使用一個已經存在的對象去初始化另一個同類的對象。

通過等于號復制對象時歉眷,系統(tǒng)會自動調用拷貝構造函數。

拷貝構造函數與原來的構造函數實現(xiàn)了函數的重載颤枪。

拷貝構造函數具有以下特點:

(1) 因為該函數也是一種構造函數,所以其函數名與類名相同,并且該函數也沒有返回值類型汗捡。

(2) 該函數只有一個參數,并且是同類對象的引用。

(3) 每個類都必須有一個拷貝構造函數畏纲。程序員可以根據需要定義特定的拷貝構造函數,以實現(xiàn)同類對象之間數據成員的傳遞扇住。如果程序員沒有定義類的拷貝構造函數,系統(tǒng)就會自動生成產生一個缺省的拷貝構造函數。

5.1 自定義拷貝構造函數

自定義拷貝構造函數的一般形式如下:

class類名{

public:

類名(形參)盗胀;//構造函數

類名(類名?&對象名)艘蹋;//拷貝構造函數

...

};

類名::?類名(類名?&對象名)//拷貝構造函數的實現(xiàn)

{?函數體?}

用戶自定義拷貝構造函數

classCoord{

intx,y;

public:

Coord(inta票灰,intb)//?構造函數

{

x=a;

y=b;

cout<<"Using?normal?constructor\n";

}

Coord(constCoord&?p)//?拷貝構造函數

{

x=2*p.x;

y=2*p.y;

cout<<"Using?copy?constructor\n";

}

//…

};

如果p1女阀、 p2為類Coord的兩個對象,p1已經存在屑迂,則coord p2(p1)調用拷貝構造函數來初始化p2

例2.19 自定義拷貝構造函數的使用

#include<iostream.h>

classCoord{

public:

Coord(inta,intb)//?構造函數

{?x=a;?y=b;cout<<"Using?normal?constructor\n";}

Coord(constCoord&?p)//?拷貝構造函數

{?x=2*p.x;?y=2*p.y;cout<<"Using?copy?constructor\n";}

voidprint(){cout<

private:

intx,y;

};

main()

{

Coordp1(30,40);//?定義對象p1,調用了普通的構造函數

Coordp2(p1);//?以“代入”?法調用拷貝構造函數,用對象p1初始化對象p2

p1.print();

p2.print();

return0;

}

除了用代入法調用拷貝構造函數外浸策,還可以采用賦值法調用拷貝構造函數,如:

main()

{

Coordp1(30,40);

Coord?p2=p1;//以"賦值"法調用拷貝構造函數惹盼,

用對象p1初始化對象p2

//…

}

5.2 缺省的拷貝構造函數

如果沒有編寫自定義的拷貝構造函數,C++會自動地將一個已存在的對象復制給新對象,這種按成員逐一復制的過程由是缺省拷貝構造函數自動完成的的榛。

例2.20 調用缺省的拷貝構造函數

#include<iostream.h>

classCoord{

public:

Coord(inta,intb)

{?x=a;?y=b;cout<<"Using?normal?constructor\n";?}

voidprint(){cout<

private:

intx,y;

};

main()

{

Coordp1(30,40);//?定義類Coord的對象p1,

//?調用了普通構造函數初始化對象p1

Coordp2(p1);//?以“代入”法調用缺省的拷貝構造函數,

//?用對象p1初始化對象p2

Coord?p3=p1;//?以“賦值”法調用缺省的拷貝構造函數,

//?用對象p1初始化對象p3

p1.print();?p2.print();?p3.print();

return0;

}

5.3 調用拷貝構造函數的三種情況

(1) 當用類的一個對象去初始化該類的另一個對象時。

Coordp2(p1);//?用對象p1初始化對象p2,?拷貝構造函數被調用(代入法)

Coord?p3=p1;//?用對象p1初始化對象p3,?拷貝構造函數被調用(賦值法)

(2) 當函數的形參是類的對象,調用函數,進行形參和實參結合時逻锐。

//…

fun1(Coord?p)//?函數的形參是類的對象

{

p.print();

}

main()

{

Coordp1(10,20);

fun1(p1);//?當調用函數,進行形參和實參結合時,

調用拷貝構造函數

return0;

}

(3) 當函數的返回值是對象,函數執(zhí)行完成,返回調用者時。

//?…

Coordfun2()

{

Coordp1(10,30);

returnp1;

}//?函數的返回值是對象

main()

{

Coord?p2;

P2=fun2();//?函數執(zhí)行完成,返回調用者時,調用拷貝構造函數

return0;

}

5.4 淺拷貝和深拷貝

所謂淺拷貝雕薪,就是由缺省的拷貝構造函數所實現(xiàn)的數據成員逐一賦值昧诱,若類中含有指針類型數據, 則會產生錯誤所袁。

為了解決淺拷貝出現(xiàn)的錯誤盏档,必須顯示地定義一個自己的拷貝構造函數,使之不但拷貝數據成員燥爷,而且為對象1和對象2分配各自的內存空間蜈亩,這就是所謂的深拷貝。

例2.23 淺拷貝例子

#include<iostream.h>

#include<string.h>

classStudent{

public:

Student(char*name1,floatscore1);

~Student();

private:

char*name;//?學生姓名

floatscore;//?學生成績

};

Student∷Student(char*name1,floatscore1)

{

cout<<"Constructing..."<

name=newchar[strlen(name1)+1];

if(name?!=0)

{

strcpy(name,name1);

score=score1;

}

}

Student∷~Student()

{

cout<<"Destructing..."<

name[0]='\0';

deletename;

}

voidmain()

{

Studentstu1("liming",90);//?定義類Student的對象stu1

Student?stu2=stu1;//?調用缺省的拷貝構造函數

}

Constructing...?liming

Destructing...?liming

Destructing...

淺拷貝示意圖

例2.24 深拷貝例子

#include<iostream.h>

#include<string.h>

classStudent{

private:

char*name;//?學生姓名

floatscore;//?學生成績

public:

Student(char*name1,floatscore1);

Student(Student&?stu);

~Student();

};

Student∷Student(char*name1,floatscore1)

{

cout<<"constructing..."<

name=newchar[strlen(name1)+1];

if(name?!=0)

{

strcpy(name,name1);

score=score1;

}

}

Student∷Student(Student&?stu)

{

cout<<"Copy?constructing..."<

name=newchar[strlen(stu.name)+1];

if(name?!=0)

{

strcpy(name,stu.name);

score=stu.score;

}

}

Student∷~Student()

{

cout<<"Destructing..."<

name[0]='\0';

deletename;

}

voidmain()

{

Studentstu1("liming"前翎,90);//?定義類Student的對象stu1稚配,

Student?stu2=stu1;//?調用自定義的拷貝構造函數

}

深拷貝示意圖

6、析構函數

析構函數也是一種特殊的成員函數港华。它執(zhí)行與構造函數相反的操作,通常用于撤消對象時的一些清理任務,如釋放分配給對象的內存空間等道川。

析構函數有以下一些特點:

① 析構函數與構造函數名字相同,但它前面必須加一個波浪號(~);

② 析構函數沒有參數,也沒有返回值,而且不能重載。因此在一個類中只能有一個析構函數;

③ 當撤消對象時,編譯系統(tǒng)會自動地調用析構函數。 如果程序員沒有定義析構函數冒萄,系統(tǒng)將自動生成和調用一個默認析構函數臊岸,默認析構函數只能釋放對象的數據成員所占用的空間,但不包括堆內存空間尊流。

例2.25 重新說明類Date

#include<iostream.h>

classDate{

public:

Date(inty,intm,intd);//?構造函數

~Date();//?析構函數

voidsetDate(inty,intm,intd);

voidshowDate();

private:

intyear,?month,?day;

};

Date::Date(inty,intm,intd)//?構造函數的實現(xiàn)

{

cout<<"constructing..."<

year=y;month=m;?day=d;

}

Date::~Date()//?析構函數的實現(xiàn)

{cout<<"destruting..."<

voidDate::setDate(inty,intm,intd)

{?year=y;month=m;day=d;?}

inlinevoidDate::showDate()

{cout<

voidmain()

{

Datedate1(1998,4,28);//?定義類Date的對象date1,

//?調用date1的構造函數,初始化對象date1

cout<<"Date1?output1:"<

date1.showDate();//?調用date1的showDate(),顯示date1的數據

date1.setDate(2002,11,14);//?調用date1的setDate(),

//?重新設置date1的數據

cout<<"Date1?output2:"<

date1.showDate();//?調用date1的showDate(),顯示date1的數據

}

析構函數被調用的兩種情況

1) 若一個對象被定義在一個函數體內帅戒,當這個函數結束時,析構函數被自動調用崖技。

2) 若一個對象是使用new運算符動態(tài)創(chuàng)建逻住,在使用delete釋放時,自動調用析構函數响疚。

【例2.13】 較完整的學生類例子

#include<iostream.h>

#include<string.h>

classStudent{

public:

Student(char*name1,char*stu_no1,floatscore1);//?構造

函數

~Student();//?析構函數

voidmodify(floatscore1);//?修改數據

voidshow();//?顯示數據

private:

char*name;//?學生姓名

char*stu_no;//?學生學號

floatscore;//?學生成績

};

Student∷Student(char*name1,char*stu_no1,floatscore1)

{

name=newchar[strlen(name1)+1];

strcpy(name,name1);

stu_no=newchar[strlen(stu_no1)+1];

strcpy(stu_no,stu_no1);

score=score1;

}

Student∷~Student()

{

delete[]name;

delete[]stu_no;

}

voidStudent∷modify(floatscore1)

{?score=score1;?}

voidStudent∷show()

{

cout<<"\n?name:?"<

cout<<"\n?stu_no:?"<

cout<<"\n?score:?"<

}

voidmain()

{

Studentstu1("Liming","990201",90);//?定義類Student的對象stu1,

//?調用stu1的構造函數,初始化對象stu1

stu1.show();//?調用stu1的show(),顯示stu1的數據

stu1.modify(88);//?調用stu1的modify(),修改stu1的數據

stu1.show();//?調用stu1的show(),顯示stu1修改后的數據

}

ame:Liming

stu_no:990201

score:90

name:Liming

stu_no:990201

score:88

缺省的析構函數

每個類必須有一個析構函數鄙信。

若沒有顯式地為一個類定義析構函數,編譯系統(tǒng)會自動地生成一個缺省的析構函數

其格式如下:類名::析構函數名( ){ }

classstring_data{

public:

string_data(char*)

{?str=newchar[max_len];}

~string_data()

{delete[]str;}

voidget_info(char*);

voidsent_info(char*);

private:

char*str;

intmax_len;

};

7忿晕、調用構造函數和析構函數的順序

1) 一般順序

調用析構函數的次序正好與調用構造函數的次序相反:最先被調用的構造函數装诡,其對應的(同一對象中的)析構函數最后被調用,而最后被調用的構造函數践盼,其對應的析構函數最先被調用鸦采。

2) 全局對象

在全局范圍中定義的對象(即在所有函數之外定義的對象),它的構造函數在所有函數(包括main函數)執(zhí)行之前調用咕幻。在程序的流程離開其作用域時(如main函數結束或調用exit函數)時渔伯,調用該全局對象的析構函數。

3) auto局部對象

局部自動對象(例如在函數中定義的對象)肄程,則在建立對象時調用其構造函數锣吼。如果函數被多次調用,則在每次建立對象時都要調用構造函數蓝厌。在函數調用結束玄叠、對象釋放時先調用析構函數。

4) static局部對象

如果在函數中定義靜態(tài)局部對象拓提,則只在程序第一次調用此函數建立對象時調用構造函數一次读恃,在調用結束時對象并不釋放,因此也不調用析構函數代态,只在main函數結束或調用exit函數結束程序時寺惫,才調用析構函數。

8. 對象的生存期

對象按生存期的不同分為如下幾種:

(1) 局部對象

當對象被定義時蹦疑,調用構造函數西雀,該對象被創(chuàng)建;當程序退出該對象所在的函數體或程序塊時歉摧,調用析構函數蒋搜,對象被釋放篡撵。

局部對象是被定義在一個函數體或程序塊內的,它的作用域限定在函數體或程序塊內豆挽,生存期較短育谬。

(2) 全局對象

當程序開始運行時,調用構造函數帮哈,該對象被創(chuàng)建膛檀;當程序結束時,調用析構函數娘侍,該對象被釋放咖刃。

靜態(tài)對象是被定義在一個文件中,它的作用域從定義是起到文件結束時為止憾筏。生存期較長嚎杨。

(3) 靜態(tài)對象

當程序中定義靜態(tài)對象時,調用構造函數氧腰,該對象被創(chuàng)建枫浙;當整個程序結束時,調用析構函數古拴,對象被釋放箩帚。

全局對象是被定義在某個文件中,它的作用域包含在該文件的整個程序中黄痪,生存期是最長的紧帕。

(4) 動態(tài)對象

執(zhí)行new運算符調用構造函數,動態(tài)對象被創(chuàng)建桅打;用delete釋放對象時是嗜,調用析構函數。

動態(tài)對象是由程序員掌握的挺尾,它的作用域和生存期是由new和delete之間的間隔決定的叠纷。

類的應用舉例(例)

一圓形游泳池如圖所示,現(xiàn)在需在其周圍建一圓形過道潦嘶,并在其四周圍上柵欄。柵欄價格為35元/米崇众,過道造價為20元/平方米掂僵。過道寬度為3米,游泳池半徑由鍵盤輸入顷歌。要求編程計算并輸出過道和柵欄的造價锰蓬。

#include<iostream>

usingnamespacestd;

constfloatPI?=3.14159;

constfloatFencePrice?=35;

constfloatConcretePrice?=20;

//聲明類Circle?及其數據和方法

classCircle{

private:

floatradius;

public:

Circle(floatr);//構造函數

floatCircumference()const;//圓周長

/*函數后的修飾符const表示該成員函數的執(zhí)行不會改變類的狀態(tài),也就是說不會修改類的數據成員眯漩。?*/

floatArea()const;//圓面積

};//?類的實現(xiàn)

//?構造函數初始化數據成員radius

Circle::Circle(floatr)

{

radius=r;

}

//?計算圓的周長

floatCircle::Circumference()const

{

return2*?PI?*?radius;

}

//?計算圓的面積

floatCircle::Area()const

{

returnPI?*?radius?*?radius;

}

voidmain()

{

floatradius;

floatFenceCost,?ConcreteCost;

//?提示用戶輸入半徑

cout<<"Enter?the?radius?of?the?pool:?";

cin>>radius;

//?聲明?Circle?對象

CirclePool(radius);

CirclePoolRim(radius?+3);

//計算柵欄造價并輸出

FenceCost=PoolRim.Circumference()*FencePrice;

cout<<"Fencing?Cost?is?¥"<

//計算過道造價并輸出

ConcreteCost=(PoolRim.Area()-

Pool.Area())*ConcretePrice;

cout<<"Concrete?Cost?is?¥"<

}

運行結果

Enter?the?radiusofthe?pool:10

Fencing?Costis¥2858.85

Concrete?Costis¥4335.39

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末芹扭,一起剝皮案震驚了整個濱河市麻顶,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌舱卡,老刑警劉巖辅肾,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異轮锥,居然都是意外死亡矫钓,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進店門舍杜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來新娜,“玉大人,你說我怎么就攤上這事既绩「帕洌” “怎么了?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵饲握,是天一觀的道長私杜。 經常有香客問我,道長互拾,這世上最難降的妖魔是什么歪今? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮颜矿,結果婚禮上寄猩,老公的妹妹穿的比我還像新娘。我一直安慰自己骑疆,他們只是感情好田篇,可當我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著箍铭,像睡著了一般泊柬。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上诈火,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天兽赁,我揣著相機與錄音,去河邊找鬼冷守。 笑死刀崖,一個胖子當著我的面吹牛,可吹牛的內容都是我干的拍摇。 我是一名探鬼主播亮钦,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼充活!你這毒婦竟也來了蜂莉?” 一聲冷哼從身側響起蜡娶,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎映穗,沒想到半個月后窖张,有當地人在樹林里發(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡男公,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年荤堪,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片枢赔。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡澄阳,死狀恐怖,靈堂內的尸體忽然破棺而出踏拜,到底是詐尸還是另有隱情碎赢,我是刑警寧澤,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布速梗,位于F島的核電站肮塞,受9級特大地震影響,放射性物質發(fā)生泄漏姻锁。R本人自食惡果不足惜枕赵,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望位隶。 院中可真熱鬧拷窜,春花似錦、人聲如沸涧黄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽笋妥。三九已至懊昨,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間春宣,已是汗流浹背酵颁。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留月帝,地道東北人躏惋。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像嫁赏,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子油挥,可洞房花燭夜當晚...
    茶點故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內容

  • 參考鏈接 一潦蝇、構造函數 C++規(guī)定款熬,每個類必須有默認的構造函數,沒有構造函數就不能創(chuàng)建對象攘乒。 若沒有提供任何構造函...
    Mitchell閱讀 2,587評論 0 4
  • 構造函數 一.構造函數的作用: 構造函數主要用于來對類的對象生成標識符贤牛,對數據成員進行初始化,和分配內存空間则酝。 相...
    loveforkeeps閱讀 441評論 0 1
  • 構造函數 每個類分別定義了對象被初始化的方式殉簸,類通過一個或幾個特殊的成員函數來控制對象的初始化過程,這些函數叫做構...
    Kai_Z閱讀 355評論 0 1
  • 轉:C++繼承中構造函數、析構函數調用順序及虛析構函數 1.構造函數 大家都知道構造函數里就可以調用成員變量爽雄,而繼...
    資深小夏閱讀 674評論 0 0
  • 心靈自由寫作11篇 “大學生祼貸”蝠检,說實在的,剛看到這個主題挚瘟,心里一點概念都沒有叹谁,雖然在新聞上也看到這方面的報道,...
    庭誼閱讀 1,866評論 0 0