C++知識(shí)點(diǎn)總結(jié)(二)

內(nèi)容比較長(zhǎng),可復(fù)制出來(lái)進(jìn)行搜索
如有錯(cuò)誤希望大家指出,僅供參考
一、子類的構(gòu)造、析構(gòu)、拷貝
????1、子類的構(gòu)造在執(zhí)行它的構(gòu)造函數(shù)前會(huì)根據(jù)繼承表的順序執(zhí)行父類的構(gòu)造函數(shù)。
????????默認(rèn)執(zhí)行父類的無(wú)參構(gòu)造
????????顯示調(diào)用有參構(gòu)造,在子類的構(gòu)造函數(shù)后,初始化列表中顯示調(diào)用父類的有參構(gòu)造函數(shù)。
????2、子類在它的析構(gòu)執(zhí)行完后,會(huì)根據(jù)繼承表的順序,逆順序執(zhí)行父類的析構(gòu)函數(shù)。
????????注意:父類的指針可以指向子類對(duì)象,當(dāng)通過(guò)父類指針釋放對(duì)象時(shí),只會(huì)調(diào)用父類的析構(gòu)函數(shù),而這種析構(gòu)方式有可能造成內(nèi)存泄漏。
????3、當(dāng)使用子類對(duì)象來(lái)初始化新的子類對(duì)象時(shí),會(huì)自動(dòng)調(diào)用子類缺省的拷貝構(gòu)造函數(shù),并且會(huì)先調(diào)用父類缺省的拷貝構(gòu)造函數(shù)。
????????如果子類中實(shí)現(xiàn)的拷貝構(gòu)造,需要顯式調(diào)用父類拷貝構(gòu)造,否則就會(huì)調(diào)用無(wú)參構(gòu)造。
二、私有繼承、保護(hù)繼承
????1、私有繼承
????使用?private?方式繼承父類,公開的變成私有,其他的不變(有爭(zhēng)議),這種繼承方式防止父類的成員擴(kuò)散。
????
????使用?protected?方式繼承父類,公開成員在子類中會(huì)變成保護(hù)的,其他不變,這種繼承方式可以有效防止父類的成員擴(kuò)散。
????子類以私有或保護(hù)方式繼承父類,會(huì)禁止向上造型(子類的指針或引用不能隱式轉(zhuǎn)換成父類的指針或引用,要想實(shí)現(xiàn)多態(tài)只能以公開方式繼承
父類)。
三、多重繼承、鉆石繼承、虛繼承
????1、多重載繼承
????在C++中一個(gè)子類可以有多個(gè)父類,在繼承表中按照順序繼承多個(gè)父類中的屬性和行為,并按照順序表,調(diào)用父類的構(gòu)造函數(shù)。
????按照從低到高的地址順序排序父類,子類中會(huì)標(biāo)記每個(gè)父類存儲(chǔ)位置。
????當(dāng)子類指針轉(zhuǎn)換成父類的隱式指針時(shí)候,編譯器會(huì)自動(dòng)計(jì)算父類中的內(nèi)容在子類中的位置,地址會(huì)自動(dòng)進(jìn)行偏移計(jì)算。
????2、名字沖突
????如果父類中有同名的成員,可以正常繼承,但如果直接使用,會(huì)造成歧義,需要?類名::成員名?進(jìn)行訪問(wèn)。
????3、鉆石繼承
????假如有一個(gè)類A,類B繼承類A,類C也繼承類A,類D繼承B和C。
????一個(gè)子類繼承多個(gè)父類,這些父類有一個(gè)共同的祖先,這種繼承叫鉆石繼承。
????注意:鉆石繼承不會(huì)導(dǎo)致繼承錯(cuò)誤,但訪問(wèn)祖先類中的成員時(shí)每次需要使用?類名::成員名?,重點(diǎn)是這種繼承會(huì)造成冗余。
????4、虛繼承?virtual
????當(dāng)進(jìn)行鉆石繼承時(shí),祖先類中的內(nèi)容會(huì)有冗余,而進(jìn)行虛繼承后,在子類中的內(nèi)容只會(huì)保留一份。
????注意:但使用虛繼承時(shí),子類中會(huì)多了一些內(nèi)容(指向從祖先類繼承來(lái)的成員)。
class?A
{
public:
????int?a;
};
class?B:virtual?public?A{};
class?C:virtual?public?A{};
class?D:public?B,public?C{};
int?main()
{
????cout<<?sizeof(B)<<endl;
????B*?p?=?new?B;
????p->a?=?100;
????A*?ap?=?p;
????A*?ap1?=?new?C;
????ap1->a?=?111;
????printf("%d?%d\n",*(int*)ap,*(int*)ap1);
//??printf("%d\n",*((int*)p+1));
//??printf("%p?%p\n",p,ap);
}
????5、構(gòu)造函數(shù)
????一旦進(jìn)行了虛繼承祖先類的構(gòu)造函數(shù)只執(zhí)行一次,由孫子類直接調(diào)用,祖先類的有參構(gòu)造也需要在孫子類中顯示調(diào)用。
????6、拷貝構(gòu)造
????在虛擬繼承(鉆石)中祖先類拷貝構(gòu)造也由孫子類直接調(diào)用,子類中不再調(diào)用祖先類的拷貝構(gòu)造,在手動(dòng)實(shí)現(xiàn)的拷貝構(gòu)造時(shí)(深拷貝),祖先
類中的內(nèi)容也由孫子類負(fù)責(zé)拷貝,同理賦值構(gòu)造也一樣。
四、虛函數(shù)、覆蓋、多態(tài)
????1、虛函數(shù)
????類的成員函數(shù)前加?virtual?這種函數(shù)就叫做虛函數(shù)。
????2、覆蓋
????子類會(huì)覆蓋父類的虛函數(shù)。
????3、多態(tài)
????當(dāng)子類覆蓋了父類的虛函數(shù)時(shí),通過(guò)父類指針指向子類對(duì)象時(shí),調(diào)用虛函數(shù),會(huì)根據(jù)具體的對(duì)象是誰(shuí)來(lái)決定執(zhí)行誰(shuí)的函數(shù),這就是多態(tài)。
class?Base
{
public:
????virtual?void?func(void)
????{
????????cout?<<?"我是Base的func函數(shù)"<<endl;
????}
};
class?A:public?Base
{
public:
????void?func(void)
????{
????????cout<<"我是類A的func函數(shù)"?<<?endl;
????}
};
class?B:public?Base
{
public:
????void?func(void)
????{
????????cout<<"我是類B的func函數(shù)"?<<?endl;
????}
};
class?C:public?Base
{
public:
????void?func(void)
????{
????????cout<<"我是類C的func函數(shù)"?<<?endl;
????}
};
int?main()
{
/*覆蓋
????A*?a?=?new?A;
????Base*?p?=?a;
????Base*?b?=?new?Base;
????b->func();?//?并沒(méi)有消失
????a->func();?//?調(diào)用子類函數(shù)
????p->func();?//?如果父類的函數(shù)是虛函數(shù),調(diào)用子類函數(shù)
*/
????srand(time(NULL));
????//?這就是多態(tài)
????Base*?arr[]?=?{new?A,new?B,new?C};
????arr[rand()%3]->func();
}
五、覆蓋和多態(tài)的條件
????1、覆蓋的條件
????????必須是虛函數(shù)
????????必須是父子類之間
????????函數(shù)簽名必須相同(參數(shù)列表完全一致,const屬性也會(huì)影響覆蓋的結(jié)果)
????????返回值必須是同類型或父子類(子類的返回值要能向父類隱式轉(zhuǎn)換)
????????訪問(wèn)屬性不會(huì)影響覆蓋
????????常函數(shù)屬性也會(huì)影響覆蓋
class?Base
{
public:
????virtual?Base*?func(void)
????//virtual?void?func(void)
????{
????????cout?<<?"我是Base的func函數(shù)"<<endl;
????}
};
class?A:public?Base
{
public:
????A*?func(void)
????//在覆蓋版本的函數(shù)中,所得到的this指針依然是實(shí)際對(duì)象地址,依然能夠調(diào)用子類中的函數(shù)。
????//void?func(int?num,char*?str)
????{
????????cout<<"我是類A的func函數(shù)"?<<?endl;
????}
};
int?main()
{
????A*?a?=?new?A;
????Base*?p?=?a;
????p->func();
}????
????
????2、重載、隱藏、覆蓋(重寫)的區(qū)別
????????重載:同一作用域下的同名函數(shù),函數(shù)簽名不同(類型、個(gè)數(shù)、順序、常函數(shù)等),構(gòu)成重載關(guān)系。
????????覆蓋:
????????????必須是虛函數(shù)
????????????必須是父子類之間
????????????函數(shù)簽名必須相同(參數(shù)列表完全一致,const屬性也會(huì)影響覆蓋的結(jié)果)
????????????返回值必須是同類型或父子類(子類的返回值要能向父類隱式轉(zhuǎn)換)
????????????訪問(wèn)屬性不會(huì)影響覆蓋
????????????常函數(shù)屬性也會(huì)影響覆蓋
????????隱藏:父子類之間的同名成員如果沒(méi)有形成覆蓋,且能通過(guò)編譯,必定構(gòu)成隱藏。
????3、多態(tài)的條件
????????1、父子類之間有的函數(shù)有覆蓋關(guān)系。
????????2、父類的指針或引用指向子類的對(duì)象。
????4、在構(gòu)造、析構(gòu)函數(shù)中調(diào)用虛函數(shù)
????????在父類的構(gòu)造函數(shù)中調(diào)用虛函數(shù),此時(shí)子類還沒(méi)有創(chuàng)建完成(回顧構(gòu)造函數(shù)的調(diào)用過(guò)程),因此只能調(diào)用父類的虛函數(shù),而不是覆蓋版本
的虛函數(shù)。
????????在父類的析構(gòu)函數(shù)中調(diào)用虛函數(shù),此時(shí)子類已經(jīng)釋放完成,因此只能調(diào)用父類的虛函數(shù),而不是覆蓋版本的虛函數(shù)。
#include?<iostream>
#include?<stdio.h>
#include?<stdlib.h>
using?namespace?std;
class?Base
{
public:
????Base(void)
????{
????????func();
????}
????virtual?void?func(void)
????{
????????cout?<<?"我是Base的func函數(shù)"<<endl;
????}
????~Base(void)
????{
????????func();
????}
};
class?A:public?Base
{
public:
????A(void)
????{
????????func();
????}
????void?func(void)
????{
????????cout<<"我是類A的func函數(shù)"?<<?endl;
????}
????~A(void)
????{
????????func();
????}
};
int?main()
{
????A?aa;
//??A*?a?=?new?A;
//??Base*?p?=?a;
//??p->func();
}
六、純虛函數(shù)和抽象類
????1、純虛函數(shù)
????在虛函數(shù)的聲明的后面添加=0,這種虛函數(shù)就叫做純虛函數(shù),可以不實(shí)現(xiàn),但如果實(shí)現(xiàn)必須在類外(只能在父類的構(gòu)造函數(shù)、析構(gòu)函數(shù)中調(diào)用)。
????virtual?返回值?函數(shù)名(參數(shù))?=?0;
#include?<iostream>
#include?<stdio.h>
using?namespace?std;
class?Base
{
public:
????Base(void)
????{
????????func();
????}
????//?純虛函數(shù)
????virtual?void?func(void)?=?0;
????~Base(void)
????{
????????func();
????}
};
class?A:public?Base
{
public:
????void?func(void)
????{
????????cout?<<?"我是純虛函數(shù)的覆蓋"<<endl;
????}
};
void?Base::func(void)
{
????cout<<?"我是虛函數(shù)"?<<?endl;
}
int?main()
{
????A?a;
????a.func();
????//Base?b;
????//b.func();
}
????2、抽象類
????成員函數(shù)中有純虛函數(shù),這種類叫抽象類,抽象類不能實(shí)例化(不能創(chuàng)建對(duì)象)。
????抽象類必須被繼承且純虛函數(shù)被覆蓋后,由子類實(shí)例化對(duì)象。
????如果繼承抽象類,但沒(méi)有覆蓋純虛函數(shù),那么子類也將成為抽象類,不能實(shí)例化。
????3、純抽象類
????所有成員函數(shù)都是純虛函數(shù),這種只能被繼承的類叫純抽象類。
????這種類一般用來(lái)設(shè)計(jì)接口,這種類在子類被替換后不需要修改或少量的修改即可繼續(xù)使用。
#include?<iostream>
using?namespace?std;
class?Base
{
public:
????virtual?void?show(void)?=?0;
};
class?A:public?Base
{
public:
????void?show(void)
????{
????????cout?<<?"我是類A的show函數(shù)"?<<?endl;
????}
};
class?B:public?Base
{
public:
????void?show(void)
????{
????????cout?<<?"我是類B的show函數(shù)"?<<?endl;
????}
};
class?C:public?Base
{
public:
????void?show(void)
????{
????????cout?<<?"我是類C的show函數(shù)"?<<?endl;
????}
};
enum?ClassType{typeA,typeB,typeC};
//?工廠類模式
Base*?creat_object(ClassType?type)
{
????switch(type)
????{
????????case?typeA:?return?new?A;
????????case?typeB:?return?new?B;
????????case?typeC:?return?new?C;
????????default:?return?NULL;
????}
}
int?main()
{
????Base*?p?=?creat_object(typeA);
????p->show();
}

一、虛函數(shù)表
????什么是虛函數(shù)表,在C++的類中,一旦成員函數(shù)中有虛函數(shù),這個(gè)類中就會(huì)多一個(gè)虛函數(shù)表指針,這個(gè)指針指向一個(gè)虛函數(shù)表,表里面記錄了
這個(gè)類中所有的虛函數(shù),當(dāng)這個(gè)類被繼承,它的子類中也會(huì)有一個(gè)虛函數(shù)表(不管子類中有沒(méi)有虛函數(shù)),如果子類的成員函數(shù)中有函數(shù)簽名與父
類的虛函數(shù)一樣,就會(huì)用子類中的函數(shù)替換它在虛函數(shù)表中的位置,這樣就達(dá)到了覆蓋的效果。
????當(dāng)通過(guò)類指針或引用調(diào)用函數(shù)時(shí),會(huì)根據(jù)對(duì)象中實(shí)際的虛函數(shù)表記錄來(lái)調(diào)用函數(shù),這樣就達(dá)到了多態(tài)的效果。
????多態(tài)類中的虛函數(shù)表建立在編譯階段。
二、虛析構(gòu)
????當(dāng)使用delete釋放一個(gè)父類指針時(shí),不管實(shí)際指向的對(duì)象是子類還是父類都只會(huì)調(diào)用父類的析構(gòu)函數(shù)(多態(tài)肯定會(huì)出現(xiàn)的問(wèn)題)。
????如果子類的析構(gòu)函數(shù)有需要負(fù)責(zé)釋放的內(nèi)存,就會(huì)造成內(nèi)存泄漏。
????為了解決這個(gè)問(wèn)題,可以把父類的析構(gòu)函數(shù)設(shè)置為虛函數(shù),析構(gòu)函數(shù)進(jìn)行覆蓋時(shí)不會(huì)比較函數(shù)名。
????當(dāng)父類的析構(gòu)函數(shù)為虛函數(shù)時(shí),通過(guò)父類指針或引用釋放子類對(duì)象時(shí),會(huì)自動(dòng)調(diào)用子類的析構(gòu)函數(shù),子類的析構(gòu)函數(shù)執(zhí)行完成后也會(huì)調(diào)用父類
的析構(gòu)函數(shù)。
????注意:析構(gòu)函數(shù)可以是虛函數(shù),但構(gòu)造函數(shù)不行
三、強(qiáng)制類型轉(zhuǎn)換
????注意:C++中為了兼容C語(yǔ)言,(目標(biāo)類型)源類型?依然可以繼續(xù)使用,但C語(yǔ)言的強(qiáng)制類型轉(zhuǎn)換安全性差,因此建議使用C++中的強(qiáng)制類型轉(zhuǎn)換。
????注意:C++之父認(rèn)為如果代碼設(shè)計(jì)的完善,根本不需要用到強(qiáng)制類型轉(zhuǎn)換,而C++的強(qiáng)制類型轉(zhuǎn)換之所以設(shè)計(jì)的很復(fù)雜,是為了讓程序員多關(guān)注
代碼本身的設(shè)計(jì),盡量少使用。
????
????C++中的強(qiáng)制類型轉(zhuǎn)換保證沒(méi)有很大安全隱患。
????static_cast<目標(biāo)類型>(源類型)???編譯器會(huì)對(duì)源類型和目標(biāo)類型做兼容性檢查,不通過(guò)則報(bào)錯(cuò)。
????dynamic_cast<目標(biāo)類型>(源類型)??編譯器會(huì)對(duì)源類型和目標(biāo)類是否同為指針或引用,并且存在多態(tài)型的繼承關(guān)系。
????const_cast<目標(biāo)類型>(源類型)????編譯器會(huì)對(duì)源類型和目標(biāo)類檢查,是否同為指針或引用,除了常屬性外其他必須完全相同,否則報(bào)錯(cuò)。
????reinterpret_cast<目標(biāo)類型>(源類型)??編譯器會(huì)對(duì)源類型和目標(biāo)類是否為指針或整數(shù)進(jìn)行檢查,也就是說(shuō)把整數(shù)轉(zhuǎn)換成指針或把指針轉(zhuǎn)換
為整數(shù)。
拓展:
????靜態(tài)編譯:指針或引用的目標(biāo)是確定的,在編譯時(shí)期就確定了所有的類型檢查、函數(shù)調(diào)用。
????動(dòng)態(tài)編譯:指針或引用的目標(biāo)是不確定的(多態(tài)),只有在函數(shù)調(diào)用的時(shí)候才確定具體是哪一個(gè)子類。
四、I/O流
????I/O流的打開模式:
????????ios::in?????以讀權(quán)限打開文件,不存在則失敗,存在不清空
????????ios::out????以寫權(quán)限打開文件,不存在則創(chuàng)建,存在則清空
????????ios::app????打開文件用于追加,不存在則創(chuàng)建,存在不清空
????????ios::binary?以二進(jìn)制模式進(jìn)行讀寫
????????ios::ate????打開時(shí)定位到文件末尾
????????ios::trunc??打開文件時(shí)清空
????fstream/ifstream/ofstream?類用于進(jìn)行文件操作。
????????構(gòu)造函數(shù)或成員函數(shù)?open?用于打開文件
????????good成員函數(shù)檢查流是否可用
????????eof成員函數(shù)用于輸入流是否結(jié)束
????>>?操作符用于從文件中讀取數(shù)據(jù)到變量
????<<?操作符用于輸出數(shù)據(jù)到文件
????IO流有一系列格式化控制函數(shù),類似:左對(duì)齊、右對(duì)齊、寬度、填充、小數(shù)點(diǎn)位數(shù)。
#include?<iostream>
#include?<fstream>
using?namespace?std;
int?main()
{
????fstream?fsi("test.txt",ios::in);
????//fs.open("test.txt",ios::in);
????if(!fsi.good())
????{
????????cout?<<"打開失敗"<<endl;
????}
????else
????{
????????cout?<<"打開成功"<<endl;
????}
????string?str,s1,s2,s3;
????int?num?=?0;
/*??fsi?>>?str;?//讀到空格或換行就停止
????fsi?>>?num?>>?s1?>>?s2?>>?s3;
????cout<<str<<"-"<<num<<"-"<<s1<<"-"<<s2<<"-"<<s3<<endl;
*/
????string?arr[10];
????int?i?=?0;
????while(1)
????{
????????fsi?>>?arr[i];
????????if(arr[i].size()?==?0)
????????{
????????????break;
????????}
????????i++;
????}
????for(int?j=0;?j<i;?j++)
????{
????????cout?<<?arr[j]?<<"-";
????}
????fstream?fso("test.txt",ios::out);
????fso?<<?"hehe"?<<?"?"?<<?100?<<"?"?<<"adsadsad"<<endl;
}
????二進(jìn)制讀寫:read/write
????????read?(char_type?*__s,streamsize?__n)
????????write?(char_type?*__s,streamsize?__n)
????????gcount成員函數(shù)可以獲取上次流的二進(jìn)制讀寫操作的字節(jié)數(shù)。
????隨機(jī)讀寫:
????????seekp?(off_type,ios_base::seekdir)
????????功能:設(shè)置文件的位置指針。
????????off_type:偏移值
????????????正值向右,負(fù)值向左
????????seekdir:基礎(chǔ)位置
????????????ios::beg????文件開頭
????????????ios::cur????當(dāng)前位置
????????????ios::end????文件末尾
#include?<fstream>
int?main()
{
????fstream?fs("test.txt",ios::in);
????if(!fs.good())
????{
????????cout?<<?"文件打開失敗"?<<?endl;
????????return?-1;
????}
????//?調(diào)整文件的位置指針到末尾
????fs.seekp(0,ios::end);
????cout?<<?"文件的字節(jié)數(shù):"?<<?fs.tellp()?<<?endl;
????fs.close();
}
int?main(int?argc,char*?argv[])//?寫的有點(diǎn)問(wèn)題0.0
{
????if(argc?!=?3)
????{
????????cout?<<?"命令錯(cuò)誤"?<<?endl;
????}
????//?讀寫
????fstream?fi(argv[1],ios::in);
????fstream?fo(argv[2],ios::out);
????if(!fi.good())
????{
????????cout?<<?"源文件不存在"?<<?endl;
????}
????cout?<<?"是否要覆蓋目標(biāo)文件,y/n"?<<?endl;
????while(1)
????{
????????string?a;
????????cin?>>?a;
????????if(a?==?"y")
????????{
????????????break;
????????}
????????else?if(a?==?"n")
????????{
????????????return?0;
????????}
????????else
????????{
????????????cout?<<?"指令錯(cuò)誤"?<<?endl;
????????????continue;
????????}
????}
????while(1)
????{
????????string?str;
????????fi?>>?str;
????????if(str.size()?==?0)
????????{
????????????break;
????????}
????????fo?<<?str?<<"?";?//?文件末尾多個(gè)空格,需要?jiǎng)h除,并且沒(méi)有換行功能
????}
}
五、類型信息?typeid
????用于獲取數(shù)據(jù)的類型信息。
????name成員函數(shù),可以獲取類型的名字,內(nèi)建類型名字使用縮寫。
????同時(shí)還支持?==?!=?用來(lái)比較是否是同一種類型。
????如果用于判斷父子類的指針或引用,它不能準(zhǔn)確判斷出實(shí)際的對(duì)象類型。但可以判斷出具有多態(tài)繼承關(guān)系的父子類的指針或引用,它的實(shí)際對(duì)象。
#include?<iostream>
#include?<typeinfo>
using?namespace?std;
class?Base
{
public:
????virtual?~Base(void)
????{
????}
};
class?Test:public?Base
{
};
int?main()
{
????Base?b;
????Test?t;
????cout?<<?typeid(b).name()?<<?endl;
????cout?<<?(typeid(t)?==?typeid(b))?<<?endl;
????cout?<<?endl;
????Base*?p?=?new?Test;
????cout?<<?(typeid(*p)?==?typeid(Test))?<<?endl;
????cout?<<?(typeid(p)?==?typeid(Test*))?<<?endl;
}
????擴(kuò)展:
????????sudo?find?/?-name?filename
????????sudo?find?/?|?grep?"std"
????????grep?'Base'?*???????????????當(dāng)前目錄查找包含此字符的文件
????????grep?-r?'Base'?*????????????當(dāng)前目錄及所有子級(jí)目錄,查找包含此字符的文件
????????grep?-r?'Base'?*?dir????????指定目錄下及所有子級(jí)目錄,查找包含此字符的文件
五、異常處理
????拋異常
????????throw?數(shù)據(jù)
????????拋異常對(duì)象
????????拋基本類型
????????注意:不能拋出局部對(duì)象的指針或引用(構(gòu)造函數(shù)和析構(gòu)函數(shù)不能拋出異常)。
????????注意:如果異常沒(méi)有被捕獲處理,程序就會(huì)停止。
????捕獲異常
????????try{
????????????可以拋出異常的代碼
????????}
????????catch(類型?變量名)?//?根據(jù)數(shù)據(jù)類型進(jìn)行捕獲
????????{
????????????處理異常,如果無(wú)法處理可以繼續(xù)拋出異常
????????}
????????注意:捕獲異常的順序是自上而下的,而不是最精準(zhǔn)的匹配,針對(duì)子類異常捕獲時(shí)要放在父類的前面。
????????函數(shù)的異常聲明:
????????????返回值類型?函數(shù)名(參數(shù)列表)throw(類型1,類型2,...)
????????????注意:如果不寫異常聲明表示什么類型的異常都可能拋出。
????????????注意:如果寫了異常聲明表示只拋出某些類型的異常,一旦超出異常聲明的范圍,程序會(huì)直接停止,無(wú)法捕獲。
????????????注意:throw()?表示什么類型都不會(huì)拋出
????????????
????????設(shè)計(jì)異常類:
????????class?Error
????????{
????????????int?errno;
????????????char?errmsg[255];
????????public:
????????????Error(int?errno?=?-1,const?char*?msg?=?"未知錯(cuò)誤")
????????????{
????????????????this->errno?=?errno;
????????????????strcpy(errmsg,msg);
????????????}
????????????int?getError(void)
????????????{
????????????????return?errno;
????????????}
????????????const?char*?getErrmsg(void)
????????????{
????????????????return?errmsg;
????????????}
????????}