第11章 重載及模板_第1頁
第11章 重載及模板_第2頁
第11章 重載及模板_第3頁
第11章 重載及模板_第4頁
第11章 重載及模板_第5頁
已閱讀5頁,還剩46頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

第11章重載與模板編譯時的多態(tài)性是通過函數(shù)重載和模板體現(xiàn)的。利用函數(shù)重載機制,在調(diào)用同名的函數(shù)時,編譯系統(tǒng)可根據(jù)實參的具體情況確定所調(diào)用的是同名函數(shù)中的哪一個。利用函數(shù)模板,編譯系統(tǒng)可根據(jù)模板實參以及模板函數(shù)實參的具體情況確定所要調(diào)用的是哪個函數(shù),并生成相應(yīng)的函數(shù)實例;運算符重載是函數(shù)重載的一種特殊情況。利用類模板,編譯系統(tǒng)可根據(jù)模板實參的具體情況確定所要定義的是哪個類的對象,并生成相應(yīng)的類實例?!?1.1重載定義

函數(shù)重載(functionoverloading)是指一個函數(shù)名稱具有不同形式的參數(shù)的若干個(兩個以上)函數(shù)的定義。注意:重載函數(shù)可以具有相同的返回類型.但必須有不同類型的參數(shù)列表。用不同返回類型和相同參數(shù)表生成重載函數(shù)將產(chǎn)生語法錯誤。編譯器只用參數(shù)列表的數(shù)據(jù)類型區(qū)別同名函數(shù)。重載函數(shù)不一定要有相同個數(shù)的參數(shù),它們可以有不同個數(shù)的參數(shù)列表。程序員使用帶默認值參數(shù)的重載函數(shù)時要小心,以免出現(xiàn)歧義。一、運算符重載引入類的對象(即抽象數(shù)據(jù)類型的實例)的操作是通過向?qū)ο蟀l(fā)送消息完成其功能的(即調(diào)用成員函數(shù)的形式)。對某些類(特別是有些數(shù)值計算類)來說,這種調(diào)用方式是繁瑣的,而用C++中的豐富的內(nèi)部運算符來指定對對象的操作會更容易表達和理解。定義把C++中的運算符和類的對象結(jié)合在一起形成有意義的表達式,這個過程稱為運算符重載。+-*/%^&|~!=<>+=-=*=/=%=^=&=|=<<>>>>=<<===!=<=>=&&||++--,[]()newnew[]deletedelete[]

C++語言中可以重載的運算符

C++語言中不能被重載的運算符

.->::?:sizeof注意:重載不能改變運算符的優(yōu)先級。雖然重載具有固定優(yōu)先級的運算符可能會不便使用,但是在表達式中使用圓括號可以強制改變重載運算符的計算順序。重載不能改變運算符的結(jié)合律。重載不能改變運算符操作數(shù)的個數(shù)。重載的一目運算符仍然是一目運算符,重載的二目運算符仍然是二目運算符,但C++中的唯一的三目運算符(?:)也不能被重載。運算符&、*、+和-既可以用作一元運算符,也可以用作二目運算符,可以分別把他們重載為一目運算符和二目運算符。重載不能創(chuàng)建新的運算符,只有現(xiàn)有的運算符才能被重載。運算符重載不能改變該運算符用于內(nèi)部類型對象時的含義。例如,程序不能改變運算符+用于兩個整數(shù)相加的含義。運算符重載通常和用戶自定義的類類型的對象一起使用,或者類類型的對象和內(nèi)部類型的對象混合運算。運算符重載函數(shù)說明的一般形式如下:<類類型>operator<運算符>(<參數(shù)說明>);

運算符重載函數(shù)定義的一般形式如下:<類類型><類類型名稱>::operator<運算符>(<參數(shù)說明>){<語句序列>}用于類的對象的運算符必須重載,但有兩種情況需要注意:賦值運算符“=”無需重載就可用于每一個類類型。在沒有重載賦值運算符時,賦值運算符的缺省行為是復(fù)制對象的數(shù)據(jù)成員。但是,這種缺省的復(fù)制行為用于帶有指針成員的對象時是危險的,該情況通常需要顯式重載賦值運算符。地址運算符&也無需重載就可以用于任何類的對象,它返回對象在內(nèi)存中的地址。地址運算符也可以被重載。

當一個類重載了賦值運算符=和加法運算符+,下列語句是允許的:

object2=object2+object1;但并不意味運算符+=也被自動重載了。因此,下面的語句是錯誤的:

object2+=object1;然而,顯式地重載運算符+=可使上述語句成立。運算符重載函數(shù)既可以是類的成員函數(shù),也可以是非成員函數(shù)。非成員函數(shù)通常是友元函數(shù)。成員函數(shù)是用this指針隱式地訪問類的對象參數(shù),非成員函數(shù)的調(diào)用必須明確地列出類的對象參數(shù)。不管運算符重載函數(shù)是成員函數(shù)還是非成員函數(shù),運算符在表達式中的使用方式是相同的。

運算符重載函數(shù)的實現(xiàn)方式通常根據(jù)下列情況來選擇:當運算式子的左邊操作數(shù)(或者只有左邊的操作數(shù))是定義類的一個對象(或者是對象的引用),運算符重載函數(shù)可以實現(xiàn)為定義類的一個成員函數(shù)。當左邊的操作數(shù)可能是另一個不同類的對象(或者為一個內(nèi)部類型的操作數(shù)),運算符重載函數(shù)必須要用一個非成員函數(shù)來實現(xiàn)。由于運算符重載函數(shù)為類的非成員函數(shù),當需要訪問類的對象的隱藏成員時,則必須指定為該類一個友元函數(shù)?!纠?1.1】實現(xiàn)復(fù)數(shù)類并重載有關(guān)的運算符。//Complex.h-存放類定義的文件classCComplex//定義一個復(fù)數(shù)類{public: CComplex(doublem_re=0,doublem_im=0);//含有缺省值的構(gòu)造函數(shù) CComplex(CComplex&x);//復(fù)制構(gòu)造函數(shù) CComplexoperator+(doublex);//實現(xiàn)左邊為該類對象與一個double數(shù)相加 CComplexoperator+(CComplex&x);//實現(xiàn)左邊為該類對象與一個該類的對象相加 CComplexoperator-(CComplex&x);//實現(xiàn)左邊為該類對象與一個該類的對象相減 CComplexoperator*(CComplex&x);//實現(xiàn)左邊為該類對象與一個該類的對象相乘 CComplexoperator/(CComplex&x);//實現(xiàn)左邊為該類對象與一個該類的對象相除 voidPrint();private: doublere;//存放實部 doubleim;//存放虛部};//Complex.cpp-存放類定義的實現(xiàn)部分和主函數(shù)#include"Complex.h"#include"iostream.h"CComplex::CComplex(doublem_re,doublem_im){ re=m_re; im=m_im;}CComplexCComplex::operator+(doublex){ doubler,i; r=re+x; i=im; CComplexy(r,i); return(y);}CComplexCComplex::operator+(CComplex&x){ doubler,i; r=re+x.re; i=im+x.im; CComplexy(r,i); return(y);}CComplexCComplex::operator-(CComplex&x){ doubler,i; r=re-x.re; i=im-x.im; return(CComplex(r,i));//返回匿名對象}CComplexCComplex::operator*(CComplex&x){ doubler,i; r=re*x.re-im*x.im; i=re*x.im+im*x.re; return(CComplex(r,i));}CComplexCComplex::operator/(CComplex&x){ doubler,i; r=(re*x.re+im*x.im)/(x.re*x.re+x.im*x.im); i=(im*x.re-re*x.im)/(x.re*x.re+x.im*x.im); return(CComplex(r,i));}CComplex::CComplex(CComplex&x){ re=x.re; im=x.im;}voidCComplex::Print(){ cout<<re<<"+"<<im<<"i"<<endl;}voidmain(void){ CComplexa(3,6),b(9,5); a.Print(); b.Print(); CComplexc; c=a+b; c.Print();c=a+6; c.Print();}輸出結(jié)果:3+6i↙9+5i↙12+11i↙9+6i↙二、類型轉(zhuǎn)換在C++語言中,兩個相同的內(nèi)部數(shù)據(jù)類型的運算其結(jié)果還是這種數(shù)據(jù)類型,例如,整數(shù)加整數(shù)還是整數(shù)。但是,還有一種需要將一種數(shù)據(jù)類型的數(shù)據(jù)轉(zhuǎn)換為另一種數(shù)據(jù)類型的數(shù)據(jù)的運算,如賦值、混合數(shù)據(jù)類型的計算、函數(shù)實參傳遞數(shù)值以及函數(shù)返回值等等,都可能會發(fā)生這種情況。對于內(nèi)部數(shù)據(jù)類型的情況,編譯器知道如何隱式地進行類型的轉(zhuǎn)換,也可以用強制類型轉(zhuǎn)換運算符來實現(xiàn)內(nèi)部類型之間的強制轉(zhuǎn)換。但用戶自定義數(shù)據(jù)類型轉(zhuǎn)換,編譯器不知道怎樣實現(xiàn)與其它數(shù)據(jù)類型之間的轉(zhuǎn)換,程序必須要明確地指明如何轉(zhuǎn)換。這種轉(zhuǎn)換可以用轉(zhuǎn)換構(gòu)造函數(shù)實現(xiàn),也可以用單個參數(shù)的構(gòu)造函數(shù)實現(xiàn)。這種構(gòu)造函數(shù)僅僅把其他類型(通常是內(nèi)部數(shù)據(jù)類型)的對象轉(zhuǎn)換為某個特定類的對象。

強制類型轉(zhuǎn)換運算符(簡稱為轉(zhuǎn)換運算符)可以把一個類的對象轉(zhuǎn)換為其他類的對象或內(nèi)部類型的對象。該運算符重載函數(shù)必須是一個非static成員函數(shù)(不能是友元函數(shù))。例如,下面的強制類型轉(zhuǎn)換的運算符重載函數(shù)的函數(shù)原型:

A::operatorchar*()const;

說明了一個強制類型轉(zhuǎn)換的運算符重載函數(shù),它根據(jù)用戶自定義類型A的對象建立一個臨時的char*類型的對象。強制類型轉(zhuǎn)換的運算符重載函數(shù)不能指定返回類型(返回類型是要轉(zhuǎn)換后的對象類型)。如果s是一個自定義類類型的對象,當編譯器遇到表達式(char*)s時,程序會產(chǎn)生函數(shù)調(diào)用s.operatorchar*(),操作數(shù)s是調(diào)用成員函數(shù)operatorchar*的類對象s。

為了把用戶自定義類型的對象轉(zhuǎn)換為內(nèi)部數(shù)據(jù)類型的的對象或者為其他用戶自定義數(shù)據(jù)類型的對象,可以定義強制類型轉(zhuǎn)換的運算符重載函數(shù)。例如,下面給出兩個強制類型轉(zhuǎn)換的運算符重載函數(shù)的函數(shù)原型:

A::operatorint()const;A::operatorotherClass()const;其中,第一個強制類型轉(zhuǎn)換的運算符重載函數(shù)用來把用戶自定義類型A的對象轉(zhuǎn)換為一個整數(shù),第二個強制類型轉(zhuǎn)換的運算符重載函數(shù)轉(zhuǎn)換為otherClass類型的對象。

強制類型轉(zhuǎn)換的運算符重載函數(shù)一個很好的特點是:當需要的時候,編譯器可以為建立一個臨時對象而自動地調(diào)用這個函數(shù)。例如,如果用戶自定義的類String的一個對象s出現(xiàn)在程序中需要使用char*類型的對象的位置上:Strings;cout<<s;編譯器調(diào)用重載的強制類型轉(zhuǎn)換運算符函數(shù)operatorchar*將對象轉(zhuǎn)換為char*類型,并在表達式中使用轉(zhuǎn)換后的char*類型的結(jié)果。String類提供該轉(zhuǎn)換運算符后,不需要重載流插入運算符用cout輸出String。三、特殊運算符的重載增一“++”和減一“—”運算符分為前置和后置的增一及減一運算符,它們都可以被重載。下面將介紹編譯器如何識別前置和后置的增一“++”運算符及減一“—”運算符。重載既能允許前置又能允許后置的增一運算符,每個這種運算符重載函數(shù)必須有一個明確的特征以使編譯器能確定要使用哪個“++”版本。前置增一“++”運算符重載函數(shù)的方法與重載其他前置一目運算符一樣。

【例11.2】用運算符重載實現(xiàn)CDate類的操作。類CDate中,重載的前置和后置增一運算符將一個CDate對象增加1天,必要時使年、月遞增。類CDate的Public接口提供了以下成員函數(shù):一個重載的流插入運算符,一個默認的構(gòu)造函數(shù)、一個setDate函數(shù)、一個重載的前置自增運算符函數(shù)、一個重載的后置自增運算符函數(shù)、一個重載的加法賦值運算符(+=)、一個檢測閏年的函數(shù)和一個判斷是否為每月最后一天的函數(shù)。#include<iostream.h>classCDate{ friendostream&operator<<(ostream&output,constCDate&d);public:CDate(intm=1,intd=1,inty=1900);voidsetDate(int,int,int); //設(shè)定日期CDate&operator++(); //前置自增運算符CDateoperator++(int); //后置自增運算符constCDate&operator+=(int);//增加指定天數(shù)到當前日期上boolleapYear(int); //是否閏年 boolendOfMonth(int); //是否為每月最后一天private: intmonth,day,year; staticconstintdays[]; //每月天數(shù) voidhelpIncrement(); //計算日期};//date.cpp-CDate類的成員函數(shù)定義和主函數(shù)定義#include"date.h"constintCDate::days[]={0,31,28,31,30,31,30,31,31,30,31,30,31};//初始化CDate::CDate(intm,intd,inty){ setDate(m,d,y);}voidCDate::setDate(intmm,intdd,intyy){month=(mm>=1&&mm<=12)?mm:1;year=(yy>=1900&&yy<=2100)?yy:1900;//判斷是否閏年if(month==2&&leapYear(year))day=(dd>=1&&dd<=29)?dd:1;elseday=(dd>=1&&dd<=days[month])?dd:1;}CDate&CDate::operator++(){helpIncrement();return*this;//返回當前對象}CDateCDate::operator++(int){CDatetemp=*this;helpIncrement();returntemp;//返回Date類型的對象}constCDate&CDate::operator+=(intadditionalDays)//增加指定天數(shù)到當前日期上{for(inti=0;i<additionalDays;i++) helpIncrement();return*this; }boolCDate::leapYear(inty)//判斷是否閏年{if(y%400==0||(y%100!=0&&y%4==0))returntrue;//是閏年elsereturnfalse;//不是閏年}boolCDate::endOfMonth(intd){if(month==2&&leapYear(year))returnd==29;//lastdayofFeb.inleapyearelsereturnd==days[month];}voidCDate::helpIncrement()//計算日期函數(shù){if(endOfMonth(day)&&month==12)//年末 {day=1;month=1;++year; }elseif(endOfMonth(day))//月末 {day=1;++month; }else++day;}ostream&operator<<(ostream&output,constCDate&d){staticchar*monthName[13]={"","January","February","March","April","May","June","July","August","September","October","November","December"}; output<<monthName[d.month]<<''<<d.day<<","<<d.year;returnoutput;}voidmain(void){ CDated1,d2(12,27,1992),d3(0,99,8045); cout<<"d1is"<<d1 <<"\nd2is"<<d2 <<"\nd3is"<<d3<<"\n"; cout<<"d2+7is"<<(d2+=7)<<"\n"; d3.setDate(2,28,1992); cout<<"d3is"<<d3; cout<<"\n++d3is"<<++d3<<"\n"; CDated4(3,18,1969); cout<<"Testingthepreincrementoperator:\n" <<"d4is"<<d4<<'\n'; cout<<"++d4is"<<++d4<<'\n'; cout<<"d4is"<<d4<<"\n"; cout<<"Testingthepostincrementoperator:\n"<<"d4is"<<d4<<'\n'; cout<<"d4++is"<<d4++<<'\n'; cout<<"d4is"<<d4<<endl;}輸出結(jié)果:dlisJanuary1,1900↙d2isDecember27,1992↙d3isJanuary1,1900↙d2+=7isJanuary3,1993↙d3isFebruary28,1992↙++d3isFebruary29,1992↙Testingthepreincrementoperator:↙d4isMarch18,1969↙++d4isMarch19,1969↙d4isMarch19,1969↙Testingthepreincrementoperator:↙d4isMarch19,1969↙d4++isMarch19,1969↙d4isMarch20,1969↙

C++語言的運算符的操作數(shù)個數(shù)、優(yōu)先級和結(jié)合性是其三個最基本的特性。在重載運算符時,應(yīng)盡可能保持基原有的特性,而無須采取專門的措施。

重載運算符時需要注意下列問題:是否要求第一操作數(shù)就是左值操作數(shù);是否修改其第一操作數(shù);操作的結(jié)果是否為左值數(shù)據(jù);保證第二操作數(shù)不被改變。

§11.2模板函數(shù)模板

所謂函數(shù)模板是一系列相關(guān)函數(shù)的模型,這些函數(shù)的源代碼形式相同,只是所針對的數(shù)據(jù)類型不同而已。

類模板類模板是一系列相關(guān)類的模型,這些類的成員組成相同,成員函數(shù)的源代碼形式相同,所不同的只是所針對的類型(包括數(shù)據(jù)成員的類型、成員函數(shù)的參數(shù)類型以及函數(shù)返回值的類型)。一、函數(shù)模板函數(shù)模板定義的一般形式如下:template〈typename<類型名稱1>,typename<類型名稱2>,……typename<類型名稱n>〉<數(shù)據(jù)類型>〈函數(shù)名稱〉(<形式參數(shù)說明列表>){函數(shù)實現(xiàn)語句序列;}其中,template關(guān)鍵字表示聲明的是模板,<

>內(nèi)是模板的參數(shù),可以有一個或n個,n≥1,斜體尖括弧是語句的成分;<類型名稱i>是一個標識符,其命名符合標識符命名規(guī)則,是虛擬的類型;函數(shù)返回值的<數(shù)據(jù)類型>可以是普通類型,也可以是模板形式類型參數(shù)表中指定的<類型名稱i>的數(shù)據(jù)類型;<形式參數(shù)說明列表>中給出了函數(shù)的若干個形式參數(shù),他們可以是普通類型,也可以是模板形式類型參數(shù)表中指定的<類型名稱i>的數(shù)據(jù)類型;函數(shù)體中定義的對象參數(shù),他們可以是普通類型,也可以是模板形式類型參數(shù)表中指定的<類型名稱i>的數(shù)據(jù)類型;typename可以用class代替,它們完全等價;也可以是一個實際的數(shù)據(jù)類型,而其后的<類型名稱i>就是該實際的數(shù)據(jù)類型的類型別名。模板函數(shù)的使用形式如下:〈函數(shù)名稱〉〈<數(shù)據(jù)類型1>,…<數(shù)據(jù)類型n>〉(<實參列表>)

或者

〈函數(shù)名稱〉(<實參列表>)

【例11.3】簡單的函數(shù)模板實例#include"iostream.h"#include"stdio.h" //函數(shù)模版定義template<typenameT>Tabs(Tx)//求絕對值{ Ty; if(x>0) y=x; else y=-x; return(y);}voidmain(void){ intm=-18; cout<<"m="<<m<<endl; cout<<"abs(m)="<<abs(m)<<endl; floatn=3.5; cout<<"n="<<n<<endl; cout<<"abs(n)="<<abs(n)<<endl; doublep=-12e10; cout<<"p="<<p<<endl; cout<<"abs(p)="<<abs(p)<<endl;cout<<"abs<double>(-1979)="<<abs<double>(1979)<<endl;}輸出結(jié)果:m=-18↙abs(m)=18↙n=3.5↙abs(n)=3.5↙p=-12e010↙abs(p)=12e010↙abs<double>(-1979)=1979↙在使用函數(shù)模板時需要注意:函數(shù)模板中的每個類型參數(shù)前都要放上class關(guān)鍵字,否則屬于語法錯誤。函數(shù)模板提供了軟件復(fù)用的好處。但是請記?。罕M管函數(shù)模板只編寫一次,但程序中仍然實例化多個函數(shù)模板的副本。這些副本仍然會占用大量內(nèi)存。二、類模板類模板定義的一般形式如下:template<typename<類型名稱1>,typename<類型名稱2>,……typename<類型名稱n>>class<類模板名>{成員說明語句序列;};template<typename<類型名稱1>,typename<類型名稱2>,……typename<類型名稱n>><數(shù)據(jù)類型><類模板名><模板形參表>::<函數(shù)名>(<函數(shù)形參表>){函數(shù)體中的語句序列;}其中,template是關(guān)鍵字,表示后面要定義的是類模板;在template后用〈〉括起的是模板的數(shù)據(jù)類型參數(shù),參數(shù)可以有一個或多個,這些數(shù)據(jù)類型參數(shù)之間要用逗號隔開;typename<類型名稱i>中,關(guān)鍵字typename說明了定義的類是一個類模板,<類型名稱i>是類模板的類型參數(shù)。在類模板的定義中,<類型名稱i>可以為任意類型;類定義體中,數(shù)據(jù)成員類型或成員函數(shù)的參數(shù)、返回值以及函數(shù)體中的局部數(shù)據(jù),他們可以是普通類型,也可以是模板參數(shù)表中指定的形式化的類型;<類型名稱i>是一個標識符,其命名規(guī)則符合標識符命名規(guī)則;typename可以用class代替,它們完全等價;也可以是一個實際的數(shù)據(jù)類型,而其后的<類型名稱i>就是該實際的數(shù)據(jù)類型的類型別名。<模板形參表>是〈<類型名稱1>,<類型名稱2>,...<類型名稱n>〉類模板實例化的一般形式如下:<類模板名>〈<類型名稱1>,<類型名稱2>,...<類型名稱n>〉

其中,通過類模板實現(xiàn)一個通用的特定類類型,需要一個或多個實際的數(shù)據(jù)類型參數(shù),確定實際的數(shù)據(jù)類型形成特定的類類型,因此,類模板也常稱為參數(shù)化類類型?!纠?1.4】簡單的類模版實例#include"iostream.h"#include"stdio.h"template<typenameT,typenameP>//類模板的定義部分classCPlus{public: CPlus(); Pplus();public: Tm; Pn;};//類模板的實現(xiàn)部分template<typenameT,typenameP>CPlus<T,P>::CPlus(){}template<typenameT,typenameP>PCPlus<T,P>::plus(){ Ps; s=(P)(m+n); return(s);}voidmain(void)//用于測試類模板的程序{ CPlus<int,double>a; a.m=12; a.n=12.8766;cout<<"結(jié)果="<<a.plus()<<endl; CPlus<double,float>b; b.m=3.6543; b.n=5644.76f; cout<<"結(jié)果="<<b.plus()<<endl; CPlus<double,int>c; c.m=3.6543e+2; c.n=300; cout<<"結(jié)果="<<c.plus()<<endl;}輸出結(jié)果:結(jié)果=24.8766↙結(jié)果=5648.41↙結(jié)果=665↙從上例中我們看出,模板類與通常的類定義沒有什么不同,只是以如下所示的首部開頭:template<classT>它指出了這是一個類模板的定義,它有一類型參數(shù)T(表示所要建立的類的類型)。編程時不必專門使用標識符T,任何有意義的標識符都可以使用。在主程序定義對象的過程中(如CPlus<int,double>a語句),編譯系統(tǒng)會自動地根據(jù)需要生成相應(yīng)的類定義,這種依據(jù)類模板生成類定義的過程稱為類模板的實例化。類模板所生成的每一個類定義就是相應(yīng)類模板的一個實例類類型。在用類模板定義對象時,由于沒有像函數(shù)實參表那樣的額外信息渠道,因此無法按函數(shù)模板的方式省略模板類型實參。但是,可以為類模板的參數(shù)設(shè)置默認值。具體地說,在定義類模板時,可以為模板形參表聲明的最后若干個參數(shù)設(shè)置默認值;而這些有默認值的參數(shù)中,最后的若干個對應(yīng)實參可以在定義對象時省略?!纠?1.5】堆棧類的模板實例。如果由一個數(shù)組構(gòu)成了一個線性表,然后限定在表尾作插入、刪除操作就成為棧(也叫堆棧,用數(shù)組順序存儲空間表示的棧是一種順序棧)。//stack.h-堆棧類模板定義#include<iostream.h> template<classT>classStack{public:Stack(int=10); //默認構(gòu)造函數(shù),堆棧大小為10~Stack(){delete[]stackPtr;} boolpush(constT&); //入棧boolpop(T&); //出棧private:intsize; //堆棧大小inttop; //棧頂元素T*stackPtr; //堆棧指針boolisEmpty()const{returntop==-1;}//是否為空boolisFull()const{returntop==size-1;}//是否已滿};//stack.cpp-堆棧類模板實現(xiàn)#include"stack.h"template<classT>Stack<T>::Stack(intS){size=S>0?S:10;top=-1; //堆棧不可用stackPtr=newT[size]; //分配空間} template<classT>boolStack<T>::push(constT&pushValue){if(!isFull()){ stackPtr[++top]=pushValue; //入棧 returntrue; }returnfalse;}template<classT>boolStack<T>::pop(T&popValue){if(!isEmpty()){popValue=stackPtr[top--];

//出棧returntrue;

}returnfalse;

}//mainapp.cpp-測試堆棧模板類#include<iostream.h>#include"stack.h" intmain(){Stack<double>doubleStack(5);doublef=1.1;cout<<"PushingelementsontodoubleStack\n";while(doubleStack.push(f)){

cout<<f<<'';f+=1.1;} cout<<"\nStackisfull.cannotpush"<<f

<<"\n\nPoppingelementsfromdoubleStack\n"; while(doubleStack.pop(f))

cout<<f<<''; cout<<"\nStackisempty.Cannotpop\n"; Stack<int>intStack;inti

=1;cout<<"\nPushingelementsontointStack\n"; while(intStack.push(i)){

cout<<i<<'';

++i;} cout<<"\nStackisfull.Cannotpush"<<i

<<"\n\nPoppingelementsfromintStack\n"; while(intStack.pop(i))

cout<<i<<''; cout<<"\nStackisempty.Cannotpop\n";return0;}輸出結(jié)果:PushingelementsontodoubleStack↙1.12.23.34.45.5↙Stackisfull.Caunotpush6.6↙ PoppingelementsfromdoubleStack↙5.54.43.32.

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論