国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

C++實例教學-類的應用

2019-11-17 05:21:18
字體:
來源:轉載
供稿:網友
    類<class)的概念是面向對象程序設計的核心概念。把對數據和數據的操作和處理封裝在一個程序模塊中的方法,可以說是人們經過幾十年程序設計 實踐的經驗總結。把程序以類的形式組織成若干模塊,使其獲得了最佳的結構特性。類概念的引入使程序設計發生了革命性的轉變。從結構程序設計(SP)中以作為程序的基本模塊轉變為面向對象(OOP)程序設計中,以類作為程序的基本模塊,這一變化使程序設計技術出現了質的飛躍。
類的概念抓住了程序的本質。程序的基本元素是數據。而函數是圍繞數據進行處理和操作。抓住了數據這個“綱”,程序中關系復雜的各種函數就變得脈絡清楚,可以隨著相應的數據組合成類,類的使用使得:
* 程序設計本身更有條理了;
* 程序的可讀性更好了;
* 程序設計的過程真正象是機器部件的組裝;
* 由于程序的零部件化,使得程序的可重用性變成切實可行的事。
為了學會OOP方法,首先讓我們看看C++程序中類及其對象是怎樣工作的。

9.1 設計一個棧類
棧(stack)是程序設計過程中經常碰到朝氣一種數據結構形式,它對于數據的存放和操作有下面這樣的特點:
1) 它只有一個對數據進行存入和取出的端口;
2) 后進者先出,即最后被存入的數據將首先被取出。其形式很象一種存儲硬幣的小容器,每次只可以從頂端壓入一個硬幣,而取出也只可以從頂端進行,即后進先出。
這樣的數據存儲和治理形式在一些程序設計中很有用。例如,編譯系統中(這是一類比較復雜的程序),對于函數調用的處理、對于表達式計算的處理,都利用了棧這樣的數據結構。

下面是一個關于棧的程序:
// PRogram 6_1.h
#include<iostream.h>
const int maxsize=6;
// enum boola{false,true}; /*注:假如在TC中調試,應加上這一句*/
class stack{
float data[maxsize];
int top;
public:
stack(void);
~stack(void);
bool empty(void);
void push(float a);
float pop(void);
};
stack::stack(void)
{
top=0;
cout<<"stack initialized."<<endl;
}
stack::~stack(void)
{
cout<<"stack destoryed."<<endl;
}
bool stack::empty(void)
{
return top==0?true:false;
}
void stack::push(float a)
{
if(top==maxsize)
{
cout<<"Stack is full!"<<endl;
return;
}
data[top]=a;
top++;
}
float stack::pop(void)
{
if(top==0)
{
cout<<"Stack is underflow!"<<endl;
return 0;
}
top--;
return data[top];
}
void main()
{
stack s1,s2;
for(int i=1;i<=maxsize;i++)
s1.push(2*i);
cout<<endl;
for(i=1;i<=maxsize;i++)
cout<<s1.pop()<<" ";
for(i=1;i<maxsize;i++)
s1.push(2.5*i);
for(i=1;i<=maxsize;i++)
s2.push(s1.pop());
do
cout<<s2.pop()<<" ";
while(!(s2.empty()));
}
程序運行結果如下:
C++實例教學-類的應用
說明:
1、 第一行定義了一種用戶定義的枚舉(enum)類型,該類型的全部值在定義式中的{...}內說明,每個值是一個標識符,每一個值與一個整數對應,假如不指定的話,就按順序與0,1...相對應。
程序中定義的枚舉類型 名為bool,只有兩個值,即false和ture。即falsh=0,true=1。
C++語言中提供的枚舉類型,實際上是int類型的一個子集。每個值除了作為一個整數之外,可以由用戶給出一個標識符形式的名字。這樣比直接用0,1形式的整數更直觀,例如還可以定義這樣的枚舉類型 :
enum answer{no,yes,maybe};
enum listorde{no-order,in-order,in-reverse};
前者指明用0,1,2表示‘否',‘是'‘可能'中不同的回答,后者則用0,1,2表示一個數據序列的三種狀態:“無序”、“正序”(從小到大)、“逆序”。在程序運行中,nono-order完全和整數0起相同的作用,yes-和in-order則與整數1等價。
在11,22行指出函數empty()返回類型為bool型,即是說明該函數應返回值false或true,當然返回整數0或1都是對的。在23行其返回語句為return top==0?true:false;其中top==0是一個關系表達式,如當前int型變量top的值為0,即top==0為真(true),返回true,如當前top的值不為0,則top==0為假(false),即返回值為false。
2、5~14行為類stack的說明,其中:
class是一個要害字,指出所說明的是一個類,標識符stack是用戶為這個類起的名字。用花括號{ }括起來的是類的成員。
類stack共有7個成員:
6~7行是stack的數據成員,這兩個數據成員是stack的私有成員。
私有成員用要害字private:說明,通常這個要害字可以省略,缺省狀態下默認為private:成員。私有成員在類外不可訪問。
第8行的要害字public:指出在其后所列的成員為公有成員,類的公有成員可以在類外被引用。
9~13行是類stack的五個公有函數成員。
第9行是與類stack同名的函數成員的說明,其定義在類外的15~18行。
函數成員的定義可以在類外也可以在類里面。如把第9行改為:
stack(void) { top = 0;}
那么在類外就不用再說明該函數,這樣的在類里面說明的函數默認為內聯函數(inline)。在類外說明的函數,其函數名前必須加上"stack::"以表示該函數是類stack的一個成員。
名為stack的函數成員是類stack的一個非凡的函數成員,稱為類stack的構造函數,它有如下特征:
1) 和類同名;
2) 可有不只一個構造函數(參數表不同);
3) 無返回類型;
4) 主要完成對象的初始化工作;
5) 在說明該類的一個對象時,系統自動調用其構造函數;
6) 類說明中如未說明構造函數,系統設置一個最簡單的構造函數。
第10行是另一個非凡的函數成員,稱作析構函數,其特征為:
1) 名為“~”加上類名。
2) 無返回類型。
3) 可以定義一個或缺省。
4) 在該類的對象退出其說明區域時自動執行。
5) 主要完成該對象撤消前的善后工作。
第11行的函數成員,名為"empty",返回類型為bool型,其功能是測試一下棧是否為空。為無參過程。可以改寫為:
bool empty(void){return top==0;};
采用類內定義方式,可以取代22~24行。
第12行說明第4個函數成員push,無返回值,一個float 參數,其函數定義在類外的第25~32行,功能是把一個新的浮點數壓入堆棧中,假如發現棧已滿則輸出一個信息。
第13行的float pop(void)是最后一個函數成員,其功能為測試棧當前是否為空,如不空,把棧頂的數據取出。其定義在33~40行。

3、42~57行是主函數,或說是整個程序的入口和出口。在其中做了下面的一系列工作:
第44行說明了類stack的兩個對象s1和s2,即創建了兩個具體的棧(空棧)。
類的說明(5~40行)只是定義,說明了其對象才是真的分配了內存,并通過自動調用構造函數完成了初始化。
45!46行,對于棧s1,做了maxsize=6次壓棧操作,先后+存棧數據為:2,4,6,8,10,12。
48~49行,又對棧(對象)s1做了6次退棧操作,并依次顯示輸出結果,由輸出順序:
12 10 8 6 4 2
可以看出棧的“后進先出”的特征。
50~51行對棧s1再做壓棧處理,應注重,在執行語句50~51之前,s1,top的值應為0(為什么?)變量i的值應為maxsize+1=7,因此該while循環語句共循環6次,順序壓進棧s1的數據應為: 15,12.5,10,7,12.5,15
54!56行是把棧s2的數據逐步退棧取出并顯示輸出,其輸出的順序為:
2.5 5 7.5 10 12.5 15
從這個例子,可以了解棧的特征,同時也知道了如何對一個類的對象進行操作。
1) 首先應說明該類的對象(44行);
2) 只答應對該對象(類)的公有成員引用;
3) 引用時應以對象名限定成員名,如:
s1.push(2*i); 表示對棧s1進行壓棧操作;
s2.empty(); 表示對棧s2進行是否為空的測試。

9.2 職員檔案治理程序
是這一個簡化了的雇員檔案治理程序。其中把雇員的檔案數據和對這些數據的設置、修改、刪除等操作組成一個程序模塊。程序通過這個模塊----類的公有部分對檔案數據進行處理,實現了面向對象程序設計的“封裝”功能。
// program 6_2.cpp
#include<iostream.h>
#include<string.h>
class employee{
char *name; // 雇員姓名
short age; // 年齡
float salary; // 工資
public:
employee();
void set_name(char *);
void set_age(short a){age=a;}
void set_salary(float s){salary=s;}
void print();
~employee(){delete[]name;}
};
employee::employee()
{
name=0;
age=0;
salary=0.0;
}
void employee::set_name(char *n)
{
name=new char[strlen(n)+1];
strcpy(name,n);
}
void employee::print()
{
cout<<"Name: "<<name;
cout<<"Age: "<<age;
cout<<"Salary: "<<salary<<endl;
}
void main()
{
char *na=0;
short ag=0;
float sa=0;
na=new char[10];
employee emp[5];
for(int i=0;i<5;i++)
{
cin>>na;
cin>>ag;
cin>>sa;
emp[i].set_name(na);
emp[i].set_age(ag);
emp[i].set_salary(sa);
emp[i].print();
}
emp[3].set_salary(5100.0);
emp[3].print();
emp[1].~employee();
cin>>na;
emp[1].set_name(na);
emp[1].set_age(23);
emp[1].set_salary(2000.0);
emp[1].print();
}

說明:
這是一個簡化的雇員檔案治理程序,其中5~33行定義了一個employee類,它包含了一個雇員的檔案數據,及對這些數據的若干處理函數。
構造函數employee,它在進行結象說明時被自動調用。這時創建的是一個雇員的空檔案。
第39行說明的是一個對象數組,一次建立了五個雇員的空檔案。
set_name(),set_age(),set_salary()三個函數可用來為雇員檔案填 入姓名、年齡、工資。其中填 入姓名時要創建一個長度為該姓名字符串長度+1的字符數組,以便以字符串形式存放該雇員的姓名。
print()函數的功能是輸出該雇員的檔案內容。
析構函數~employee()的功能是當某雇員檔案撤消或改成另一姓名時,把原占用的字符串空間釋放掉。

--------------------------------------------------------------------

9.3 在平面上用直線和圓畫圖
編一個程序,以直線段、矩形和圓為基本圖元組成一圖形。
我們采用面向對象的編程方法,把直線line,矩形rectangle和圓circle設計為三個類,它們各有自己的數據和函數成員。用線、矩形和圓組合成圖形,就是對這三個類的對象進行操作。
程序代碼如下:
// program 6_3.cpp
#include<iostream.h>
#include<process.h>
#include<graph.h>
#include<conio.h>
class Line{
int startx,starty,endx,endy;
public:
Line(int sx,int sy,int ex,int ey)
{
startx=sx;
starty=sy;
endx=ex;
endy=ey;
}
void draw();
};
class Rectangle
{
int uplx,uply,lowrx,lowry;
public:
Rectangle(int ulx,int uly,int lrx,int lry)
{
uplx=ulx;
uply=uly;
lowrx=lrx;
lowry=lry;
}
void draw();
};
class Circle
{
int centx,int centy,radius;
public:
Circle(int cx,int cy,int r)
{
centx=cx;
centy=cy;
radius=r;
}
void draw();
};
void Line::draw()
{
_moveto(startx,starty);
_lineto(endx,endy);
} // 畫一條直線
void Rectangle::draw()
{
_rectangle(_GBORDER,uolx,uply,lowrx,lowry);
} // 畫一個空心矩形
void Circle::draw()
{
_ellipse(_GBORDER,centx-radius,centy-radius,centx+radius,centy+radius);
} // 畫一個圓
void main()
{
short centx,centy;
cin>>centx>>centy;
Rectangle fram1(centx-60,centy-60,centx+60,centy+60),
fram2(centx-62,centy-62,centx+62,centy+62);
Circle disk(centx,centy,55);
Line poin1(centx,centy,centx+25,centy+25),
poin2(centx,centy,centx+12,centy+40),
bar1(centx,centy+50,centx,centy+42),
bar2(centx,centy-42,centx,centy-50),
bar3(centx-50,centy,centx-42,centy),
bar4(centx+42,centy,centx+50,centy);
if(!_setvideomode(_MAXRESMODE))
exit(1);
fam1.draw();
fram2.draw();
disk.draw();
bar1.draw();
bar2.draw();
bar3.draw();
bar4.draw();
poin1.draw();
poin2.draw();
getch();
_setvideomode(_DEFAULTMODE);
}
程序說明:
1) 這是一個利用基本圖形對象直線段、矩形和圓來組成一個簡單的表形的程序。從這個程序的設計過程(雖然它比實際程序簡化了許多)可以了解面向對象程序設計的基本方式和特征。在55~79行的main函數中首先根據需要說明若干個圖元對象:兩個矩形,一個圓,六個直線段,它們正是組成顯示的圖形的各基本圖元。最后分別調用各自的draw函數,完成了顯示任務。
2) 程序中采用了在圖形模式下進行屏幕顯示的操作方式。系統的屏幕顯示可有兩種基本模式:文本模式:這是系統平時工作的模式。 圖形模式:當程序需要輸出圖形時,應把系統設為圖形模式。
用setvideomode()函數把系統由文本模式轉為圖形模式。
在各個類的draw()函數中,利用圖形庫函數完成基本圖元的生成顯示。
在6~16和41~44行,定義了一個Line類,它由四個私有成員和兩個公有成員的函數成員組成,這完全是為了簡化程序。例如,還可以為該直線段設置顏色。查閱坐標。修改數據等等操作。
在18~28行和46~48行,定義了Rectangle類。
在30~39行和50~51行,定義了Circle類。
三種類的定義,只是說明了類。在58~66行的對象說明中才有了類的具體內容,同時按照 給出的不同參數,決定了這些實際的圖元的位置和尺寸。對于Line,Rectangle,Circle這三個類,用戶可以對其進行的操作只有兩種:
1) 通過構造函數 創建具有指定參數的對象;
2) 調用公有成員函數,顯示這一圖元。
從這里可以感受到類和對象對于其數據封裝的含義。
從這個例子中,我們指出了把程序以類的形式組織起來的方法才優越性,但也應從中發現一些問題和不足的地方。例如:
三個類是互不相關的,但仔細觀察會發現類Line和類Rectangle之間本來是有內在聯系的,一個矩形實際上是由兩條橫線和兩條縱線組成的,類Rectangle的對象的創建是否可以借助于類Line的幾個對象的創建來實現呢?
另外三個類中都包含了象draw()這樣的公有函數,也許可以具有象著色color()等等這樣的共同的函數成員。
如何在程序設計中表現不同的類之間的層次關篛,相互間的相關性,這要用到其它的一些知識,如派生類、虛函數等概念和手段,使程序的組織更加合理和嚴密。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 江孜县| 龙南县| 杭州市| 绥棱县| 定日县| 永兴县| 汝州市| 九台市| 邻水| 玉门市| 永安市| 惠来县| 宽城| 宣城市| 绥宁县| 曲阜市| 宣汉县| 泌阳县| 磐安县| 陵水| 夏邑县| 舒城县| 台江县| 建湖县| 宣威市| 河曲县| 广昌县| 宜君县| 沭阳县| 兴隆县| 抚松县| 新建县| 瑞昌市| 巴中市| 闽侯县| 都匀市| 临高县| 科尔| 神木县| 囊谦县| 抚顺县|