C++系列之高級教程(一)
[toc]
C++文件和流
iostream 標(biāo)準(zhǔn)庫提供了 cin 和 cout 方法分別用于從標(biāo)準(zhǔn)輸入讀取流和向標(biāo)準(zhǔn)輸出寫入流赤赊。
本教程介紹如何從文件讀取流和向文件寫入流灸拍。這就需要用到 C++ 中另一個標(biāo)準(zhǔn)庫 fstream,它定義了三個新的數(shù)據(jù)類型:
數(shù)據(jù)類型 | 描述 |
---|---|
ofstream | 該數(shù)據(jù)類型表示輸出文件流准谚,用于創(chuàng)建文件并向文件寫入信息逮走。 |
ifstream | 該數(shù)據(jù)類型表示輸入文件流,用于從文件讀取信息。 |
fstream | 該數(shù)據(jù)類型通常表示文件流,且同時具有 ofstream 和 ifstream 兩種功能数初,這意味著它可以創(chuàng)建文件,向文件寫入信息梗顺,從文件讀取信息泡孩。 |
要在 C++ 中進(jìn)行文件處理,必須在 C++ 源代碼文件中包含頭文件 <iostream> 和 <fstream>寺谤。
打開文件
在從文件讀取信息或者向文件寫入信息之前仑鸥,必須先打開文件。ofstream 和 fstream 對象都可以用來打開文件進(jìn)行寫操作变屁,如果只需要打開文件進(jìn)行讀操作眼俊,則使用 ifstream 對象。
下面是 open() 函數(shù)的標(biāo)準(zhǔn)語法粟关,open() 函數(shù)是 fstream泵琳、ifstream 和 ofstream 對象的一個成員。
void open(const char *filename, ios::openmode mode);
在這里,open() 成員函數(shù)的第一參數(shù)指定要打開的文件的名稱和位置获列,第二個參數(shù)定義文件被打開的模式谷市。
模式標(biāo)志 | 描述 |
---|---|
ios::app | 追加模式。所有寫入都追加到文件末尾击孩。 |
ios::ate | 文件打開后定位到文件末尾迫悠。 |
ios::in | 打開文件用于讀取。 |
ios::out | 打開文件用于寫入巩梢。 |
ios::trunc | 如果該文件已經(jīng)存在创泄,其內(nèi)容將在打開文件之前被截斷,即把文件長度設(shè)為 0括蝠。 |
您可以把以上兩種或兩種以上的模式結(jié)合使用鞠抑。例如,如果您想要以寫入模式打開文件忌警,并希望截斷文件搁拙,以防文件已存在,那么您可以使用下面的語法:
ofstream outfile;
outfile.open("file.dat", ios::out | ios::trunc );
類似地法绵,您如果想要打開一個文件用于讀寫箕速,可以使用下面的語法:
ifstream afile;
afile.open("file.dat", ios::out | ios::in );
關(guān)閉文件
當(dāng) C++ 程序終止時,它會自動關(guān)閉刷新所有流朋譬,釋放所有分配的內(nèi)存盐茎,并關(guān)閉所有打開的文件。但程序員應(yīng)該養(yǎng)成一個好習(xí)慣徙赢,在程序終止前關(guān)閉所有打開的文件字柠。
下面是 close() 函數(shù)的標(biāo)準(zhǔn)語法,close() 函數(shù)是 fstream狡赐、ifstream 和 ofstream 對象的一個成員窑业。
void close();
寫入文件
在 C++ 編程中,我們使用流插入運算符( << )向文件寫入信息阴汇,就像使用該運算符輸出信息到屏幕上一樣数冬。唯一不同的是,在這里您使用的是 ofstream 或 fstream 對象搀庶,而不是 cout 對象拐纱。
讀取文件
在 C++ 編程中,我們使用流提取運算符( >> )從文件讀取信息哥倔,就像使用該運算符從鍵盤輸入信息一樣秸架。唯一不同的是,在這里您使用的是 ifstream 或 fstream 對象咆蒿,而不是 cin 對象东抹。
讀取&寫入實例
下面的 C++ 程序以讀寫模式打開一個文件蚂子。在向文件 afile.dat 寫入用戶輸入的信息之后,程序從文件讀取信息缭黔,并將其輸出到屏幕上:
#include <fstream>
#include <iostream>
using namespace std;
int main ()
{
char data[100];
// 以寫模式打開文件
ofstream outfile;
outfile.open("afile.dat");
cout << "Writing to the file" << endl;
cout << "Enter your name: ";
cin.getline(data, 100);
// 向文件寫入用戶輸入的數(shù)據(jù)
outfile << data << endl;
cout << "Enter your age: ";
cin >> data;
cin.ignore();
// 再次向文件寫入用戶輸入的數(shù)據(jù)
outfile << data << endl;
// 關(guān)閉打開的文件
outfile.close();
// 以讀模式打開文件
ifstream infile;
infile.open("afile.dat");
cout << "Reading from the file" << endl;
infile >> data;
// 在屏幕上寫入數(shù)據(jù)
cout << data << endl;
// 再次從文件讀取數(shù)據(jù)食茎,并顯示它
infile >> data;
cout << data << endl;
// 關(guān)閉打開的文件
infile.close();
return 0;
}
代碼運行結(jié)果:
$./a.out
Writing to the file
Enter your name: Zara
Enter your age: 9
Reading from the file
Zara
9
上面的實例中使用了 cin 對象的附加函數(shù),比如 getline()函數(shù)從外部讀取一行馏谨,ignore() 函數(shù)會忽略掉之前讀語句留下的多余字符别渔。
文件位置指針
istream 和 ostream 都提供了用于重新定位文件位置指針的成員函數(shù)。這些成員函數(shù)包括關(guān)于 istream 的 seekg("seek get")和關(guān)于 ostream 的 seekp("seek put")惧互。
seekg 和 seekp 的參數(shù)通常是一個長整型哎媚。第二個參數(shù)可以用于指定查找方向。查找方向可以是 ios::beg(默認(rèn)的喊儡,從流的開頭開始定位)拨与,也可以是 ios::cur(從流的當(dāng)前位置開始定位),也可以是 ios::end(從流的末尾開始定位)艾猜。
文件位置指針是一個整數(shù)值买喧,指定了從文件的起始位置到指針?biāo)谖恢玫淖止?jié)數(shù)。下面是關(guān)于定位 "get" 文件位置指針的實例:
// 定位到 fileObject 的第 n 個字節(jié)(假設(shè)是 ios::beg)
fileObject.seekg( n );
// 把文件的讀指針從 fileObject 當(dāng)前位置向后移 n 個字節(jié)
fileObject.seekg( n, ios::cur );
// 把文件的讀指針從 fileObject 末尾往回移 n 個字節(jié)
fileObject.seekg( n, ios::end );
// 定位到 fileObject 的末尾
fileObject.seekg( 0, ios::end );
C++異常處理
異常是程序在執(zhí)行期間產(chǎn)生的問題箩朴。C++ 異常是指在程序運行時發(fā)生的特殊情況岗喉,比如嘗試除以零的操作秋度。
異常提供了一種轉(zhuǎn)移程序控制權(quán)的方式炸庞。C++ 異常處理涉及到三個關(guān)鍵字:try、catch荚斯、throw埠居。
- throw: 當(dāng)問題出現(xiàn)時,程序會拋出一個異常事期。這是通過使用 throw 關(guān)鍵字來完成的滥壕。
- catch: 在您想要處理問題的地方,通過異常處理程序捕獲異常兽泣。catch 關(guān)鍵字用于捕獲異常绎橘。
- try: try 塊中的代碼標(biāo)識將被激活的特定異常。它后面通常跟著一個或多個 catch 塊唠倦。
如果有一個塊拋出一個異常称鳞,捕獲異常的方法會使用 try 和 catch 關(guān)鍵字。try 塊中放置可能拋出異常的代碼稠鼻,try 塊中的代碼被稱為保護(hù)代碼冈止。使用 try/catch 語句的語法如下所示:
try
{
// 保護(hù)代碼
}catch( ExceptionName e1 )
{
// catch 塊
}catch( ExceptionName e2 )
{
// catch 塊
}catch( ExceptionName eN )
{
// catch 塊
}
如果 try 塊在不同的情境下會拋出不同的異常,這個時候可以嘗試羅列多個 catch 語句候齿,用于捕獲不同類型的異常熙暴。
拋出異常
您可以使用 throw 語句在代碼塊中的任何地方拋出異常闺属。throw 語句的操作數(shù)可以是任意的表達(dá)式,表達(dá)式的結(jié)果的類型決定了拋出的異常的類型周霉。
以下是嘗試除以零時拋出異常的實例:
double division(int a, int b)
{
if( b == 0 )
{
throw "Division by zero condition!";
}
return (a/b);
}
捕獲異常
catch 塊跟在 try 塊后面掂器,用于捕獲異常。您可以指定想要捕捉的異常類型俱箱,這是由 catch 關(guān)鍵字后的括號內(nèi)的異常聲明決定的唉匾。
try
{
// 保護(hù)代碼
}catch( ExceptionName e )
{
// 處理 ExceptionName 異常的代碼
}
上面的代碼會捕獲一個類型為 ExceptionName 的異常。如果您想讓 catch 塊能夠處理 try 塊拋出的任何類型的異常匠楚,則必須在異常聲明的括號內(nèi)使用省略號 ...巍膘,如下所示:
try
{
// 保護(hù)代碼
}catch(...)
{
// 能處理任何異常的代碼
}
下面是一個實例,拋出一個除以零的異常芋簿,并在 catch 塊中捕獲該異常峡懈。
#include <iostream>
using namespace std;
double division(int a, int b)
{
if( b == 0 )
{
throw "Division by zero condition!";
}
return (a/b);
}
int main ()
{
int x = 50;
int y = 0;
double z = 0;
try {
z = division(x, y);
cout << z << endl;
}catch (const char* msg) {
cerr << msg << endl;
}
return 0;
}
//由于我們拋出了一個類型為 const char* 的異常,因此与斤,當(dāng)捕獲該異常時肪康,我們必須在 catch 塊中使用 const char*。當(dāng)上面的代碼被編譯和執(zhí)行時撩穿,它會產(chǎn)生下列結(jié)果:
代碼運行結(jié)果:
Division by zero condition!
C++標(biāo)準(zhǔn)的異常
C++ 提供了一系列標(biāo)準(zhǔn)的異常磷支,定義在 <exception> 中,我們可以在程序中使用這些標(biāo)準(zhǔn)的異常食寡。它們是以父子類層次結(jié)構(gòu)組織起來的雾狈,如下所示:
下表是對上面層次結(jié)構(gòu)中出現(xiàn)的每個異常的說明:
定義新的異常
可以通過繼承和重載 exception 類來定義新的異常。下面的實例演示了如何使用 std::exception 類來實現(xiàn)自己的異常:
#include <iostream>
#include <exception>
using namespace std;
struct MyException : public exception
{
const char * what () const throw ()
{
return "C++ Exception";
}
};
int main()
{
try
{
throw MyException();
}
catch(MyException& e)
{
std::cout << "MyException caught" << std::endl;
std::cout << e.what() << std::endl;
}
catch(std::exception& e)
{
//其他的錯誤
}
}
代碼運行結(jié)果:
MyException caught
C++ Exception
在這里烂琴,what() 是異常類提供的一個公共方法爹殊,它已被所有子異常類重載。這將返回異常產(chǎn)生的原因奸绷。
C++動態(tài)內(nèi)存
C++ 程序中的內(nèi)存分為兩個部分:
- 棧:在函數(shù)內(nèi)部聲明的所有變量都將占用棧內(nèi)存梗夸。
- 堆:這是程序中未使用的內(nèi)存,在程序運行時可用于動態(tài)分配內(nèi)存号醉。
很多時候無法提前預(yù)知需要多少內(nèi)存來存儲某個定義變量中的特定信息反症,所需內(nèi)存的大小需要在運行時才能確定。
在 C++ 中畔派,您可以使用特殊的運算符為給定類型的變量在運行時分配堆內(nèi)的內(nèi)存铅碍,這會返回所分配的空間地址。這種運算符即 new 運算符线椰。
如果不再需要動態(tài)分配的內(nèi)存空間胞谈,可以使用 delete 運算符,刪除之前由 new 運算符分配的內(nèi)存士嚎。
new和delete運算符
下面是使用 new 運算符來為任意的數(shù)據(jù)類型動態(tài)分配內(nèi)存的通用語法:
new data-type;
在這里呜魄,data-type 可以是包括數(shù)組在內(nèi)的任意內(nèi)置的數(shù)據(jù)類型悔叽,也可以是包括類或結(jié)構(gòu)在內(nèi)的用戶自定義的任何數(shù)據(jù)類型莱衩。讓我們先來看下內(nèi)置的數(shù)據(jù)類型。例如娇澎,我們可以定義一個指向 double 類型的指針笨蚁,然后請求內(nèi)存,該內(nèi)存在執(zhí)行時被分配趟庄。我們可以按照下面的語句使用 new 運算符來完成這點:
double* pvalue = NULL; // 初始化為 null 的指針
pvalue = new double; // 為變量請求內(nèi)存
如果自由存儲區(qū)已被用完括细,可能無法成功分配內(nèi)存。所以建議檢查 new 運算符是否返回 NULL 指針戚啥,并采取以下適當(dāng)?shù)牟僮鳎?/p>
double* pvalue = NULL;
if( !(pvalue = new double ))
{
cout << "Error: out of memory." <<endl;
exit(1);
}
malloc() 函數(shù)在 C 語言中就出現(xiàn)了奋单,在 C++ 中仍然存在,但建議盡量不要使用 malloc() 函數(shù)猫十。new 與 malloc() 函數(shù)相比览濒,其主要的優(yōu)點是呆盖,new 不只是分配了內(nèi)存,它還創(chuàng)建了對象贷笛。
在任何時候应又,當(dāng)您覺得某個已經(jīng)動態(tài)分配內(nèi)存的變量不再需要使用時,您可以使用 delete 操作符釋放它所占用的內(nèi)存乏苦,如下所示:
delete pvalue; // 釋放 pvalue 所指向的內(nèi)存
下面的實例中使用了上面的概念株扛,演示了如何使用 new 和 delete 運算符:
#include <iostream>
using namespace std;
int main ()
{
double* pvalue = NULL; // 初始化為 null 的指針
pvalue = new double; // 為變量請求內(nèi)存
*pvalue = 29494.99; // 在分配的地址存儲值
cout << "Value of pvalue : " << *pvalue << endl;
delete pvalue; // 釋放內(nèi)存
return 0;
}
代碼運行結(jié)果:
Value of pvalue : 29495
數(shù)組的動態(tài)內(nèi)存分配
假設(shè)我們要為一個字符數(shù)組(一個有 20 個字符的字符串)分配內(nèi)存,我們可以使用上面實例中的語法來為數(shù)組動態(tài)地分配內(nèi)存汇荐,如下所示:
char* pvalue = NULL; // 初始化為 null 的指針
pvalue = new char[20]; // 為變量請求內(nèi)存
要刪除我們剛才創(chuàng)建的數(shù)組洞就,語句如下:
delete [] pvalue; // 刪除 pvalue 所指向的數(shù)組
下面是 new 操作符的通用語法,可以為多維數(shù)組分配內(nèi)存掀淘,如下所示:
// 動態(tài)分配,數(shù)組長度為 m
int *array=new int [m];
//釋放內(nèi)存
delete [] array;
對象的動態(tài)內(nèi)存分配
對象與簡單的數(shù)據(jù)類型沒有什么不同奖磁。例如,請看下面的代碼繁疤,我們將使用一個對象數(shù)組來理清這一概念:
#include <iostream>
using namespace std;
class Box
{
public:
Box() {
cout << "調(diào)用構(gòu)造函數(shù)咖为!" <<endl;
}
~Box() {
cout << "調(diào)用析構(gòu)函數(shù)!" <<endl;
}
};
int main( )
{
Box* myBoxArray = new Box[4];
delete [] myBoxArray; // 刪除數(shù)組
return 0;
}
如果要為一個包含四個 Box 對象的數(shù)組分配內(nèi)存稠腊,構(gòu)造函數(shù)將被調(diào)用 4 次躁染,同樣地,當(dāng)刪除這些對象時架忌,析構(gòu)函數(shù)也將被調(diào)用相同的次數(shù)(4次)吞彤。
當(dāng)上面的代碼被編譯和執(zhí)行時,它會產(chǎn)生下列結(jié)果:
調(diào)用構(gòu)造函數(shù)叹放!
調(diào)用構(gòu)造函數(shù)饰恕!
調(diào)用構(gòu)造函數(shù)!
調(diào)用構(gòu)造函數(shù)井仰!
調(diào)用析構(gòu)函數(shù)埋嵌!
調(diào)用析構(gòu)函數(shù)!
調(diào)用析構(gòu)函數(shù)俱恶!
調(diào)用析構(gòu)函數(shù)雹嗦!
C++命名空間
假設(shè)這樣一種情況,當(dāng)一個班上有兩個名叫 Zara 的學(xué)生時合是,為了明確區(qū)分它們了罪,我們在使用名字之外,不得不使用一些額外的信息聪全,比如他們的家庭住址泊藕,或者他們父母的名字等等。
同樣的情況也出現(xiàn)在 C++ 應(yīng)用程序中难礼。例如娃圆,您可能會寫一個名為 xyz() 的函數(shù)汽久,在另一個可用的庫中也存在一個相同的函數(shù) xyz()。這樣踊餐,編譯器就無法判斷您所使用的是哪一個 xyz() 函數(shù)景醇。
因此,引入了命名空間這個概念吝岭,專門用于解決上面的問題三痰,它可作為附加信息來區(qū)分不同庫中相同名稱的函數(shù)、類窜管、變量等散劫。使用了命名空間即定義了上下文。本質(zhì)上幕帆,命名空間就是定義了一個范圍获搏。
我們舉一個計算機(jī)系統(tǒng)中的例子,一個文件夾(目錄)中可以包含多個文件夾失乾,每個文件夾中不能有相同的文件名常熙,但不同文件夾中的文件可以重名。
定義命名空間
命名空間的定義使用關(guān)鍵字 namespace碱茁,后跟命名空間的名稱裸卫,如下所示:
namespace namespace_name {
// 代碼聲明
}
為了調(diào)用帶有命名空間的函數(shù)或變量,需要在前面加上命名空間的名稱纽竣,如下所示:
name::code; // code 可以是變量或函數(shù)
讓我們來看看命名空間如何為變量或函數(shù)等實體定義范圍:
#include <iostream>
using namespace std;
// 第一個命名空間
namespace first_space{
void func(){
cout << "Inside first_space" << endl;
}
}
// 第二個命名空間
namespace second_space{
void func(){
cout << "Inside second_space" << endl;
}
}
int main ()
{
// 調(diào)用第一個命名空間中的函數(shù)
first_space::func();
// 調(diào)用第二個命名空間中的函數(shù)
second_space::func();
return 0;
}
代碼運行結(jié)果:
Inside first_space
Inside second_space
using 指令
可以使用 using namespace 指令墓贿,這樣在使用命名空間時就可以不用在前面加上命名空間的名稱。這個指令會告訴編譯器蜓氨,后續(xù)的代碼將使用指定的命名空間中的名稱聋袋。
#include <iostream>
using namespace std;
// 第一個命名空間
namespace first_space{
void func(){
cout << "Inside first_space" << endl;
}
}
// 第二個命名空間
namespace second_space{
void func(){
cout << "Inside second_space" << endl;
}
}
using namespace first_space;
int main ()
{
// 調(diào)用第一個命名空間中的函數(shù)
func();
return 0;
}
代碼運行結(jié)果:
Inside first_space
using 指令也可以用來指定命名空間中的特定項目。例如穴吹,如果您只打算使用 std 命名空間中的 cout 部分幽勒,您可以使用如下的語句:
using std::cout;
#include <iostream>
using std::cout;
int main ()
{
cout << "std::endl is used with std!" << std::endl;
return 0;
}
代碼運行結(jié)果:
std::endl is used with std!
using 指令引入的名稱遵循正常的范圍規(guī)則。名稱從使用 using 指令開始是可見的刀荒,直到該范圍結(jié)束代嗤。此時,在范圍以外定義的同名實體是隱藏的缠借。
不連續(xù)的命名空間
命名空間可以定義在幾個不同的部分中,因此命名空間是由幾個單獨定義的部分組成的宜猜。一個命名空間的各個組成部分可以分散在多個文件中泼返。
所以,如果命名空間中的某個組成部分需要請求定義在另一個文件中的名稱姨拥,則仍然需要聲明該名稱绅喉。下面的命名空間定義可以是定義一個新的命名空間渠鸽,也可以是為已有的命名空間增加新的元素:
namespace namespace_name {
// 代碼聲明
}
嵌套的命名空間
命名空間可以嵌套,您可以在一個命名空間中定義另一個命名空間柴罐,如下所示:
namespace namespace_name1 {
// 代碼聲明
namespace namespace_name2 {
// 代碼聲明
}
}
您可以通過使用 :: 運算符來訪問嵌套的命名空間中的成員:
// 訪問 namespace_name2 中的成員
using namespace namespace_name1::namespace_name2;
// 訪問 namespace:name1 中的成員
using namespace namespace_name1;
在上面的語句中徽缚,如果使用的是 namespace_name1,那么在該范圍內(nèi) namespace_name2 中的元素也是可用的革屠,如下所示:
#include <iostream>
using namespace std;
// 第一個命名空間
namespace first_space{
void func(){
cout << "Inside first_space" << endl;
}
// 第二個命名空間
namespace second_space{
void func(){
cout << "Inside second_space" << endl;
}
}
}
using namespace first_space::second_space;
int main ()
{
// 調(diào)用第二個命名空間中的函數(shù)
func();
return 0;
}
代碼運行結(jié)果:
Inside second_space
C++模板
模板是泛型編程的基礎(chǔ)凿试,泛型編程即以一種獨立于任何特定類型的方式編寫代碼。
模板是創(chuàng)建泛型類或函數(shù)的藍(lán)圖或公式似芝。庫容器那婉,比如迭代器和算法,都是泛型編程的例子党瓮,它們都使用了模板的概念详炬。
每個容器都有一個單一的定義,比如 向量寞奸,我們可以定義許多不同類型的向量呛谜,比如 vector <int> 或 vector <string>。
您可以使用模板來定義函數(shù)和類枪萄,接下來讓我們一起來看看如何使用呻率。
函數(shù)模板
模板函數(shù)定義的一般形式如下所示:
template <typename type> ret-type func-name(parameter list)
{
// 函數(shù)的主體
}
在這里,type 是函數(shù)所使用的數(shù)據(jù)類型的占位符名稱呻引。這個名稱可以在函數(shù)定義中使用礼仗。
下面是函數(shù)模板的實例,返回兩個數(shù)中的最大值:
#include <iostream>
#include <string>
using namespace std;
template <typename T>
inline T const& Max (T const& a, T const& b)
{
return a < b ? b:a;
}
int main ()
{
int i = 39;
int j = 20;
cout << "Max(i, j): " << Max(i, j) << endl;
double f1 = 13.5;
double f2 = 20.7;
cout << "Max(f1, f2): " << Max(f1, f2) << endl;
string s1 = "Hello";
string s2 = "World";
cout << "Max(s1, s2): " << Max(s1, s2) << endl;
return 0;
}
代碼運行結(jié)果:
Max(i, j): 39
Max(f1, f2): 20.7
Max(s1, s2): World
類模板
正如我們定義函數(shù)模板一樣逻悠,我們也可以定義類模板元践。泛型類聲明的一般形式如下所示:
template <class type> class class-name {
.
.
.
}
在這里,type 是占位符類型名稱童谒,可以在類被實例化的時候進(jìn)行指定单旁。您可以使用一個逗號分隔的列表來定義多個泛型數(shù)據(jù)類型。
下面的實例定義了類 Stack<>饥伊,并實現(xiàn)了泛型方法來對元素進(jìn)行入棧出棧操作:
#include <iostream>
#include <vector>
#include <cstdlib>
#include <string>
#include <stdexcept>
using namespace std;
template <class T>
class Stack {
private:
vector<T> elems; // 元素
public:
void push(T const&); // 入棧
void pop(); // 出棧
T top() const; // 返回棧頂元素
bool empty() const{ // 如果為空則返回真象浑。
return elems.empty();
}
};
template <class T>
void Stack<T>::push (T const& elem)
{
// 追加傳入元素的副本
elems.push_back(elem);
}
template <class T>
void Stack<T>::pop ()
{
if (elems.empty()) {
throw out_of_range("Stack<>::pop(): empty stack");
}
// 刪除最后一個元素
elems.pop_back();
}
template <class T>
T Stack<T>::top () const
{
if (elems.empty()) {
throw out_of_range("Stack<>::top(): empty stack");
}
// 返回最后一個元素的副本
return elems.back();
}
int main()
{
try {
Stack<int> intStack; // int 類型的棧
Stack<string> stringStack; // string 類型的棧
// 操作 int 類型的棧
intStack.push(7);
cout << intStack.top() <<endl;
// 操作 string 類型的棧
stringStack.push("hello");
cout << stringStack.top() << std::endl;
stringStack.pop();
stringStack.pop();
}
catch (exception const& ex) {
cerr << "Exception: " << ex.what() <<endl;
return -1;
}
}
代碼運行結(jié)果:
7
hello
Exception: Stack<>::pop(): empty stack