十年網(wǎng)站開(kāi)發(fā)經(jīng)驗(yàn) + 多家企業(yè)客戶 + 靠譜的建站團(tuán)隊(duì)
量身定制 + 運(yùn)營(yíng)維護(hù)+專(zhuān)業(yè)推廣+無(wú)憂售后,網(wǎng)站問(wèn)題一站解決
你說(shuō)的是c++的抽象類(lèi)
創(chuàng)新互聯(lián)于2013年成立,先為黃龍等服務(wù)建站,黃龍等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為黃龍企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問(wèn)題。
純虛函數(shù)和抽象類(lèi)
純虛函數(shù)是一種特殊的虛函數(shù),它的一般格式如下:
class 類(lèi)名
{
virtual 類(lèi)型函數(shù)名(參數(shù)表)=0;
…
};
在許多情況下,在基類(lèi)中不能對(duì)虛函數(shù)給出有意義有實(shí)現(xiàn),而把它說(shuō)明為純虛函數(shù),它的實(shí)現(xiàn)留給該基類(lèi)的派生類(lèi)去做。這就是純虛函數(shù)的作用。下面給出一個(gè)純虛函數(shù)的例子。
#include
class point
{
public:
point(int i=0, int j=0) { x0=i; y0=j; }
virtual void set() = 0;
virtual void draw() = 0;
protected:
int x0, y0;
};
class line : public point
{
public:
line(int i=0, int j=0, int m=0, int n=0):point(i, j)
{
x1=m; y1=n;
}
void set() { cout"line::set() called.\n"; }
void draw() { cout"line::draw() called.\n"; }
protected:
int x1, y1;
};
class ellipse : public point
{
public:
ellipse(int i=0, int j=0, int p=0, int q=0):point(i, j)
{
x2=p; y2=q;
}
void set() { cout"ellipse::set() called.\n"; }
void draw() { cout"ellipse::draw() called.\n"; }
protected:
int x2, y2;
};
void drawobj(point *p)
{
p-draw();
}
void setobj(point *p)
{
p-set();
}
void main()
{
line *lineobj = new line;
ellipse *elliobj = new ellipse;
drawobj(lineobj);
drawobj(elliobj);
cout setobj(lineobj);
setobj(elliobj);
cout"\nRedraw the object...\n";
drawobj(lineobj);
drawobj(elliobj);
}
抽象類(lèi)
帶有純虛函數(shù)的類(lèi)稱(chēng)為抽象類(lèi)。抽象類(lèi)是一種特殊的類(lèi),它是為了抽象和設(shè)計(jì)的目的而建立的,它處于繼承層次結(jié)構(gòu)的較上層。抽象類(lèi)是不能定義對(duì)象的,在實(shí)際中為了強(qiáng)調(diào)一個(gè)類(lèi)是抽象類(lèi),可將該類(lèi)的構(gòu)造函數(shù)說(shuō)明為保護(hù)的訪問(wèn)控制權(quán)限。
抽象類(lèi)的主要作用是將有關(guān)的組織在一個(gè)繼承層次結(jié)構(gòu)中,由它來(lái)為它們提供一個(gè)公共的根,相關(guān)的子類(lèi)是從這個(gè)根派生出來(lái)的。
抽象類(lèi)刻畫(huà)了一組子類(lèi)的操作接口的通用語(yǔ)義,這些語(yǔ)義也傳給子類(lèi)。一般而言,抽象類(lèi)只描述這組子類(lèi)共同的操作接口,而完整的實(shí)現(xiàn)留給子類(lèi)。
抽象類(lèi)只能作為基類(lèi)來(lái)使用,其純虛函數(shù)的實(shí)現(xiàn)由派生類(lèi)給出。如果派生類(lèi)沒(méi)有重新定義純虛函數(shù),而派生類(lèi)只是繼承基類(lèi)的純虛函數(shù),則這個(gè)派生類(lèi)仍然還是一個(gè)抽象類(lèi)。如果派生類(lèi)中給出了基類(lèi)純虛函數(shù)的實(shí)現(xiàn),則該派生類(lèi)就不再是抽象類(lèi)了,它是一個(gè)可以建立對(duì)象的具體類(lèi)了。
您好,很高興回答您的問(wèn)題。
由于沒(méi)有看到其他的內(nèi)容所以只能從結(jié)構(gòu)上來(lái)說(shuō)明相關(guān)含義。
void digdisplay()表示的是這個(gè)函數(shù)的定義,其中void表示函數(shù)不帶任何的返回值,digdisplay表示的是函數(shù)名,括號(hào)中表示函數(shù)的參數(shù),這里是空的,所以表示不帶任何的返回值。
以上就是我的回答,敬請(qǐng)指正。
如果定義函數(shù)時(shí)只給出一對(duì)花括號(hào){}而不給出其局部變量和函數(shù)體語(yǔ)句,則稱(chēng)該函數(shù)為“空函數(shù)”。
空函數(shù)的作用:
(1)程序設(shè)計(jì)過(guò)程的需要。在設(shè)計(jì)模塊時(shí),對(duì)于一些細(xì)節(jié)問(wèn)題或功能在以后需要時(shí)再加上。這樣可在將來(lái)準(zhǔn)備擴(kuò)充的地方寫(xiě)上一個(gè)空函數(shù),這樣可使程序的結(jié)構(gòu)清晰,可讀性好,而且易于擴(kuò)充。
(2)在C++程序中,可以將基類(lèi)中的虛函數(shù)定義為空函數(shù),通過(guò)派生類(lèi)去實(shí)例化,實(shí)現(xiàn)多態(tài)。
對(duì)于你所說(shuō)的“void表示主函數(shù)為空函數(shù),沒(méi)有返回值”:
void 函數(shù)名(參數(shù));這種形式的函數(shù)定義,是說(shuō)所定義的函數(shù)沒(méi)有返回值。沒(méi)有返回值(也就是函數(shù)體內(nèi)沒(méi)有return語(yǔ)句),是指函數(shù)只是完成一系列動(dòng)作,不需要返回值給調(diào)用函數(shù);或者返回值是通過(guò)指針等方式返回給調(diào)用函數(shù)的。
有虛函數(shù)的話就有虛表,虛表保存虛函數(shù)地址,一個(gè)地址占用的長(zhǎng)度根據(jù)編譯器不同有可能不同,vs里面是8個(gè)字節(jié),在devc++里面是4個(gè)字節(jié)。類(lèi)和結(jié)構(gòu)體的對(duì)齊方式相同,有兩條規(guī)則
1、數(shù)據(jù)成員對(duì)齊規(guī)則:結(jié)構(gòu)(struct)(或聯(lián)合(union))的數(shù)據(jù)成員,第一個(gè)數(shù)據(jù)成員放在offset為0的地方,以后每個(gè)數(shù)據(jù)成員的對(duì)齊按照#pragma pack指定的數(shù)值和這個(gè)數(shù)據(jù)成員自身長(zhǎng)度中,比較小的那個(gè)進(jìn)行。
2、結(jié)構(gòu)(或聯(lián)合)的整體對(duì)齊規(guī)則:在數(shù)據(jù)成員完成各自對(duì)齊之后,結(jié)構(gòu)(或聯(lián)合)本身也要進(jìn)行對(duì)齊,對(duì)齊將按照#pragma pack指定的數(shù)值和結(jié)構(gòu)(或聯(lián)合)最大數(shù)據(jù)成員長(zhǎng)度中,比較小的那個(gè)進(jìn)行
下面是我收集的關(guān)于內(nèi)存對(duì)齊的一篇很好的文章:
在最近的項(xiàng)目中,我們涉及到了“內(nèi)存對(duì)齊”技術(shù)。對(duì)于大部分程序員來(lái)說(shuō),“內(nèi)存對(duì)齊”對(duì)他們來(lái)說(shuō)都應(yīng)該是“透明的”。“內(nèi)存對(duì)齊”應(yīng)該是編譯器的 “管轄范圍”。編譯器為程序中的每個(gè)“數(shù)據(jù)單元”安排在適當(dāng)?shù)奈恢蒙?。但是C語(yǔ)言的一個(gè)特點(diǎn)就是太靈活,太強(qiáng)大,它允許你干預(yù)“內(nèi)存對(duì)齊”。如果你想了解更加底層的秘密,“內(nèi)存對(duì)齊”對(duì)你就不應(yīng)該再透明了。
一、內(nèi)存對(duì)齊的原因
大部分的參考資料都是如是說(shuō)的:
1、平臺(tái)原因(移植原因):不是所有的硬件平臺(tái)都能訪問(wèn)任意地址上的任意數(shù)據(jù)的;某些硬件平臺(tái)只能在某些地址處取某些特定類(lèi)型的數(shù)據(jù),否則拋出硬件異常。
2、性能原因:數(shù)據(jù)結(jié)構(gòu)(尤其是棧)應(yīng)該盡可能地在自然邊界上對(duì)齊。原因在于,為了訪問(wèn)未對(duì)齊的內(nèi)存,處理器需要作兩次內(nèi)存訪問(wèn);而對(duì)齊的內(nèi)存訪問(wèn)僅需要一次訪問(wèn)。
二、對(duì)齊規(guī)則
每個(gè)特定平臺(tái)上的編譯器都有自己的默認(rèn)“對(duì)齊系數(shù)”(也叫對(duì)齊模數(shù))。程序員可以通過(guò)預(yù)編譯命令#pragma pack(n),n=1,2,4,8,16來(lái)改變這一系數(shù),其中的n就是你要指定的“對(duì)齊系數(shù)”。
規(guī)則:
1、數(shù)據(jù)成員對(duì)齊規(guī)則:結(jié)構(gòu)(struct)(或聯(lián)合(union))的數(shù)據(jù)成員,第一個(gè)數(shù)據(jù)成員放在offset為0的地方,以后每個(gè)數(shù)據(jù)成員的對(duì)齊按照#pragma pack指定的數(shù)值和這個(gè)數(shù)據(jù)成員自身長(zhǎng)度中,比較小的那個(gè)進(jìn)行。
2、結(jié)構(gòu)(或聯(lián)合)的整體對(duì)齊規(guī)則:在數(shù)據(jù)成員完成各自對(duì)齊之后,結(jié)構(gòu)(或聯(lián)合)本身也要進(jìn)行對(duì)齊,對(duì)齊將按照#pragma pack指定的數(shù)值和結(jié)構(gòu)(或聯(lián)合)最大數(shù)據(jù)成員長(zhǎng)度中,比較小的那個(gè)進(jìn)行。
3、結(jié)合1、2顆推斷:當(dāng)#pragma pack的n值等于或超過(guò)所有數(shù)據(jù)成員長(zhǎng)度的時(shí)候,這個(gè)n值的大小將不產(chǎn)生任何效果。
三、試驗(yàn)
我們通過(guò)一系列例子的詳細(xì)說(shuō)明來(lái)證明這個(gè)規(guī)則吧!
我試驗(yàn)用的編譯器包括GCC 3.4.2和VC6.0的C編譯器,平臺(tái)為Windows XP + Sp2。
我們將用典型的struct對(duì)齊來(lái)說(shuō)明。首先我們定義一個(gè)struct:
#pragma pack(n) /* n = 1, 2, 4, 8, 16 */
struct test_t {
int a;
char b;
short c;
char d;
};
#pragma pack(n)
首先我們首先確認(rèn)在試驗(yàn)平臺(tái)上的各個(gè)類(lèi)型的size,經(jīng)驗(yàn)證兩個(gè)編譯器的輸出均為:
sizeof(char) = 1
sizeof(short) = 2
sizeof(int) = 4
我們的試驗(yàn)過(guò)程如下:通過(guò)#pragma pack(n)改變“對(duì)齊系數(shù)”,然后察看sizeof(struct test_t)的值。
1、1字節(jié)對(duì)齊(#pragma pack(1))
輸出結(jié)果:sizeof(struct test_t) = 8 [兩個(gè)編譯器輸出一致]
分析過(guò)程:
1) 成員數(shù)據(jù)對(duì)齊
#pragma pack(1)
struct test_t {
int a; /* 長(zhǎng)度4 1 按1對(duì)齊;起始o(jì)ffset=0 0%1=0;存放位置區(qū)間[0,3] */
char b; /* 長(zhǎng)度1 = 1 按1對(duì)齊;起始o(jì)ffset=4 4%1=0;存放位置區(qū)間[4] */
short c; /* 長(zhǎng)度2 1 按1對(duì)齊;起始o(jì)ffset=5 5%1=0;存放位置區(qū)間[5,6] */
char d; /* 長(zhǎng)度1 = 1 按1對(duì)齊;起始o(jì)ffset=7 7%1=0;存放位置區(qū)間[7] */
};
#pragma pack()
成員總大小=8
2) 整體對(duì)齊
整體對(duì)齊系數(shù) = min((max(int,short,char), 1) = 1
整體大小(size)=$(成員總大小) 按 $(整體對(duì)齊系數(shù)) 圓整 = 8 /* 8%1=0 */ [注1]
2、2字節(jié)對(duì)齊(#pragma pack(2))
輸出結(jié)果:sizeof(struct test_t) = 10 [兩個(gè)編譯器輸出一致]
分析過(guò)程:
1) 成員數(shù)據(jù)對(duì)齊
#pragma pack(2)
struct test_t {
int a; /* 長(zhǎng)度4 2 按2對(duì)齊;起始o(jì)ffset=0 0%2=0;存放位置區(qū)間[0,3] */
char b; /* 長(zhǎng)度1 2 按1對(duì)齊;起始o(jì)ffset=4 4%1=0;存放位置區(qū)間[4] */
short c; /* 長(zhǎng)度2 = 2 按2對(duì)齊;起始o(jì)ffset=6 6%2=0;存放位置區(qū)間[6,7] */
char d; /* 長(zhǎng)度1 2 按1對(duì)齊;起始o(jì)ffset=8 8%1=0;存放位置區(qū)間[8] */
};
#pragma pack()
成員總大小=9
2) 整體對(duì)齊
整體對(duì)齊系數(shù) = min((max(int,short,char), 2) = 2
整體大小(size)=$(成員總大小) 按 $(整體對(duì)齊系數(shù)) 圓整 = 10 /* 10%2=0 */
3、4字節(jié)對(duì)齊(#pragma pack(4))
輸出結(jié)果:sizeof(struct test_t) = 12 [兩個(gè)編譯器輸出一致]
分析過(guò)程:
1) 成員數(shù)據(jù)對(duì)齊
#pragma pack(4)
struct test_t {
int a; /* 長(zhǎng)度4 = 4 按4對(duì)齊;起始o(jì)ffset=0 0%4=0;存放位置區(qū)間[0,3] */
char b; /* 長(zhǎng)度1 4 按1對(duì)齊;起始o(jì)ffset=4 4%1=0;存放位置區(qū)間[4] */
short c; /* 長(zhǎng)度2 4 按2對(duì)齊;起始o(jì)ffset=6 6%2=0;存放位置區(qū)間[6,7] */
char d; /* 長(zhǎng)度1 4 按1對(duì)齊;起始o(jì)ffset=8 8%1=0;存放位置區(qū)間[8] */
};
#pragma pack()
成員總大小=9
2) 整體對(duì)齊
整體對(duì)齊系數(shù) = min((max(int,short,char), 4) = 4
整體大小(size)=$(成員總大小) 按 $(整體對(duì)齊系數(shù)) 圓整 = 12 /* 12%4=0 */
4、8字節(jié)對(duì)齊(#pragma pack(8))
輸出結(jié)果:sizeof(struct test_t) = 12 [兩個(gè)編譯器輸出一致]
分析過(guò)程:
1) 成員數(shù)據(jù)對(duì)齊
#pragma pack(8)
struct test_t {
int a; /* 長(zhǎng)度4 8 按4對(duì)齊;起始o(jì)ffset=0 0%4=0;存放位置區(qū)間[0,3] */
char b; /* 長(zhǎng)度1 8 按1對(duì)齊;起始o(jì)ffset=4 4%1=0;存放位置區(qū)間[4] */
short c; /* 長(zhǎng)度2 8 按2對(duì)齊;起始o(jì)ffset=6 6%2=0;存放位置區(qū)間[6,7] */
char d; /* 長(zhǎng)度1 8 按1對(duì)齊;起始o(jì)ffset=8 8%1=0;存放位置區(qū)間[8] */
};
#pragma pack()
成員總大小=9
2) 整體對(duì)齊
整體對(duì)齊系數(shù) = min((max(int,short,char), 8) = 4
整體大小(size)=$(成員總大小) 按 $(整體對(duì)齊系數(shù)) 圓整 = 12 /* 12%4=0 */
5、16字節(jié)對(duì)齊(#pragma pack(16))
輸出結(jié)果:sizeof(struct test_t) = 12 [兩個(gè)編譯器輸出一致]
分析過(guò)程:
1) 成員數(shù)據(jù)對(duì)齊
#pragma pack(16)
struct test_t {
int a; /* 長(zhǎng)度4 16 按4對(duì)齊;起始o(jì)ffset=0 0%4=0;存放位置區(qū)間[0,3] */
char b; /* 長(zhǎng)度1 16 按1對(duì)齊;起始o(jì)ffset=4 4%1=0;存放位置區(qū)間[4] */
short c; /* 長(zhǎng)度2 16 按2對(duì)齊;起始o(jì)ffset=6 6%2=0;存放位置區(qū)間[6,7] */
char d; /* 長(zhǎng)度1 16 按1對(duì)齊;起始o(jì)ffset=8 8%1=0;存放位置區(qū)間[8] */
};
#pragma pack()
成員總大小=9
2) 整體對(duì)齊
整體對(duì)齊系數(shù) = min((max(int,short,char), 16) = 4
整體大小(size)=$(成員總大小) 按 $(整體對(duì)齊系數(shù)) 圓整 = 12 /* 12%4=0 */
四、結(jié)論
8字節(jié)和16字節(jié)對(duì)齊試驗(yàn)證明了“規(guī)則”的第3點(diǎn):“當(dāng)#pragma pack的n值等于或超過(guò)所有數(shù)據(jù)成員長(zhǎng)度的時(shí)候,這個(gè)n值的大小將不產(chǎn)生任何效果”。另外內(nèi)存對(duì)齊是個(gè)很復(fù)雜的東西,上面所說(shuō)的在有些時(shí)候也可能不正確。呵呵^_^
[注1]
什么是“圓整”?
舉例說(shuō)明:如上面的8字節(jié)對(duì)齊中的“整體對(duì)齊”,整體大小=9 按 4 圓整 = 12
圓整的過(guò)程:從9開(kāi)始每次加一,看是否能被4整除,這里9,10,11均不能被4整除,到12時(shí)可以,則圓整結(jié)束。
多態(tài)性是指用一個(gè)名字定義不同的函數(shù),這函數(shù)執(zhí)行不同但又類(lèi)似的操作,從而實(shí)現(xiàn)“一個(gè)接口,多種方法”。
多態(tài)性的實(shí)現(xiàn)與靜態(tài)聯(lián)編、動(dòng)態(tài)聯(lián)編有關(guān)。靜態(tài)聯(lián)編支持的多態(tài)性稱(chēng)為編譯時(shí)的多態(tài)性,也稱(chēng)靜態(tài)多態(tài)性,它是通過(guò)函數(shù)重載和運(yùn)算符重載實(shí)現(xiàn)的。動(dòng)態(tài)聯(lián)編支持的多態(tài)性稱(chēng)為運(yùn)行時(shí)的多態(tài)性,也稱(chēng)動(dòng)態(tài)多態(tài)性,它是通過(guò)繼承和虛函數(shù)實(shí)現(xiàn)的。
2.函數(shù)重載
函數(shù)重載的意義在于他能用同一個(gè)名字訪問(wèn)一組相關(guān)的函數(shù)。
在類(lèi)中普通成員函數(shù)和構(gòu)造函數(shù)都可以重載,特別是構(gòu)造函數(shù)的重載(他提供了多種初使化方式)給用戶更大的靈活性。在基類(lèi)和派生類(lèi)的函數(shù)重載有兩種情況:一種是參數(shù)有所差別的重載。另一種是參數(shù)沒(méi)有差別的重載,只是他們屬于不同的類(lèi)。
可以用以下兩種方法來(lái)區(qū)分這兩種函數(shù):用對(duì)象名加以區(qū)分;使用“類(lèi)名::”加以區(qū)分。
3.運(yùn)算符重載稱(chēng)動(dòng)態(tài)多態(tài)性,他是通過(guò)繼承和虛函數(shù)實(shí)現(xiàn)的。
運(yùn)算符重載通過(guò)創(chuàng)建運(yùn)算符函數(shù)operator@()來(lái)實(shí)現(xiàn)。運(yùn)算符函數(shù)定義了重載的運(yùn)算符將要進(jìn)行的操作,這種操作通常作用在一個(gè)類(lèi)上。這樣,在編譯時(shí)遇到名為operator@的運(yùn)算符函數(shù)(@表示所要重載的運(yùn)算符),就檢查傳遞給函數(shù)的參數(shù)的類(lèi)型。
重載運(yùn)算符與預(yù)定義運(yùn)算符的使用方法完全相同,它不能改變?cè)羞\(yùn)算符的參數(shù)個(gè)數(shù)(單目或雙目),也不能改變?cè)械膬?yōu)先級(jí)的結(jié)合性。用戶不能定義新的運(yùn)算符,只能從C++已有的運(yùn)算符中選擇一個(gè)恰當(dāng)?shù)倪\(yùn)算符重載。
3.1成員運(yùn)算符函數(shù)
運(yùn)算符函數(shù)可以定義為它將要操作的類(lèi)的成員(稱(chēng)為成員運(yùn)算符函數(shù)),也可以定義為非類(lèi)的成員,但是非成員的運(yùn)算符函數(shù)大多是類(lèi)的友元函數(shù)(稱(chēng)為友元運(yùn)算符函數(shù))。
成員運(yùn)算符函數(shù)在類(lèi)中的聲明格式為:
class X{
//……
type operator@(參數(shù)表);
};
其中type為函數(shù)的返回類(lèi)型,@為所要重載的運(yùn)算符符號(hào),X是重載此運(yùn)算符的類(lèi)名,參數(shù)表中羅列的是該運(yùn)算符所需要的操作數(shù)。
成員運(yùn)算符函數(shù)定義的形式一般為:
type X::operator@(參數(shù)表)
//函數(shù)體}
其符號(hào)的含義與聲明時(shí)相同。
在成員運(yùn)算符函數(shù)的參數(shù)表中,若運(yùn)算符是單目的,則參數(shù)表為空,此時(shí)當(dāng)前對(duì)象作為運(yùn)算符的一個(gè)操作數(shù),通過(guò)this指針隱含地傳遞給函數(shù)的;若運(yùn)算符是雙目的,則參數(shù)表中有一個(gè)操作數(shù),它作為運(yùn)算符的右操作參數(shù),此時(shí)當(dāng)前對(duì)象做為運(yùn)算符的左操作數(shù),它是this指針隱含地傳遞給函數(shù)的。總之成員運(yùn)算符函數(shù)operator@所需要的一個(gè)操作數(shù)是由對(duì)象通過(guò)this指針隱含傳遞。
3.2友元運(yùn)算符函數(shù)
在C++中可以把運(yùn)算符函數(shù)定義成某個(gè)類(lèi)的友元函數(shù),稱(chēng)為友元運(yùn)算符函數(shù)。
友元運(yùn)算符函數(shù)在類(lèi)的內(nèi)部聲明格式如下:
friend type operator@(參數(shù)表)
定義友元運(yùn)算符函數(shù)格式如下:
type operator@(參數(shù)表)
{ //函數(shù)體
}
與成員運(yùn)算符函數(shù)不同,友元運(yùn)算符函數(shù)是不屬于任何類(lèi)對(duì)象的,它沒(méi)有this指針。若重載的是雙目運(yùn)算符,則參數(shù)表中有兩個(gè)操作數(shù);若重載的是單目運(yùn)算符,則參數(shù)表中只有一個(gè)操作數(shù)。 不能用友元函數(shù)重載的運(yùn)算符是=、()、[]、-〉,其余的運(yùn)算符都可以使用友元函數(shù)來(lái)實(shí)現(xiàn)重載。
運(yùn)算符函數(shù)調(diào)用形式如下表:
運(yùn)算符函數(shù)調(diào)用形式
習(xí)慣形式 友元運(yùn)算符函數(shù)調(diào)用形式 成員運(yùn)算符函數(shù)調(diào)用形式
a+b operator(a,b) a.operator+(b)
-a operator-(a) a.operator-()
a++ operator++(a,0) a.operator++(0)
4.賦值運(yùn)算符
繼承C語(yǔ)言,用戶自定義的類(lèi)和結(jié)構(gòu)都要能進(jìn)行賦值運(yùn)算。而數(shù)組名不能賦值,數(shù)組名實(shí)質(zhì)上是一個(gè)常量指針。
對(duì)于任何類(lèi),C++提供了默認(rèn)的賦值運(yùn)算符。一般地,默認(rèn)的賦值運(yùn)算符重載是能夠勝任工作的。當(dāng)類(lèi)中有指針類(lèi)型時(shí),需要自定義賦值運(yùn)算符函數(shù)。一般其函數(shù)體包含兩部分:
1)與析構(gòu)函數(shù)類(lèi)似,取消對(duì)象已經(jīng)占有的資源;
2)與構(gòu)造函數(shù)類(lèi)似,在其中分配新的資源。
類(lèi)的賦值運(yùn)算符重載“=”只能重載為成員函數(shù),不能重載為友元函數(shù)。
重載后的運(yùn)算符函數(shù)operator=()不能被繼承。
拷貝構(gòu)造函數(shù)和賦值運(yùn)算符重載的區(qū)別:聲明和定義方式不同;調(diào)用方式不同。
5.虛函數(shù)
虛函數(shù)是重載的另一種表現(xiàn)形式,允許虛函數(shù)調(diào)用與函數(shù)體之間的聯(lián)系在運(yùn)行時(shí)才建立。
定義:虛函數(shù)就是在基類(lèi)中被關(guān)鍵字virtual說(shuō)明,并在派生類(lèi)中重新定義的函數(shù),在派生類(lèi)中重新定義時(shí),其函數(shù)原形包括返回類(lèi)型,函數(shù)名,參數(shù)個(gè)數(shù)與參數(shù)類(lèi)型的順序,都必須與基類(lèi)中的原形必須相同。
構(gòu)造函數(shù)不能是虛函數(shù),但析構(gòu)函數(shù)可以是虛函數(shù)。
虛函數(shù)與重載函數(shù)的關(guān)系:當(dāng)普通的函數(shù)重載時(shí),其函數(shù)的參數(shù)或參數(shù)類(lèi)型必須有所不同,函數(shù)的返回類(lèi)型也可不同;在派生類(lèi)中,重新定義虛函數(shù)時(shí)要求函數(shù)名、返回類(lèi)型、參數(shù)個(gè)數(shù)、參數(shù)的類(lèi)型和順序與基類(lèi)中的函數(shù)原形完全相同;若僅僅返回類(lèi)型不同,其余均相同,系統(tǒng)會(huì)給出錯(cuò)誤信息。虛函數(shù)重載時(shí)若僅僅函數(shù)名相同,而參數(shù)的個(gè)數(shù)、類(lèi)型或順序不同系統(tǒng)將它作為普遍函數(shù)重載,虛函數(shù)的特征將會(huì)丟失。
多重繼承與虛函數(shù):多重繼承可視為多個(gè)單繼承的組合。
6.純虛函數(shù)和抽象類(lèi)
純虛函數(shù):是一個(gè)在基類(lèi)中說(shuō)明的虛函數(shù),他在該基類(lèi)中沒(méi)有定義,但要求在它的派生類(lèi)中定義自己的版本,或重新說(shuō)明為純虛函數(shù)。
純虛函數(shù)的一般形式:virtual type func_name(參數(shù)表)=0(type是函數(shù)的返回類(lèi)型,func_name是函數(shù)名)。
抽象類(lèi):一個(gè)類(lèi)至少有一個(gè)純虛函數(shù)的類(lèi)。抽象類(lèi)提供了處理各種不同派生類(lèi)的統(tǒng)一接口,將實(shí)現(xiàn)的責(zé)任交給了派生類(lèi)。
另外,站長(zhǎng)團(tuán)上有產(chǎn)品團(tuán)購(gòu),便宜有保證
inline, static, constructor ,template 函數(shù)都不能 為虛函數(shù),而析構(gòu)函數(shù)可以。
為什么呢:
inline: 編譯器替換; 而虛函數(shù)是為了解決運(yùn)行期間綁定。
static:class 成員; 編譯期間就給class了。
constructor: 構(gòu)造函數(shù)表示要生成一個(gè)class的object;假設(shè)是virtual的,那就說(shuō)不知道這個(gè)實(shí)例化derived還是based的class。但是類(lèi)型實(shí)例化必須在編譯期確定(否則編譯器不知道到底是什么對(duì)象了)
template:模板實(shí)例是在 compile-time,virtual就意味著在run-time確定。這讓編譯器設(shè)計(jì)者為難了,這就是說(shuō)虛函數(shù)表要指向各種版本的 template function 實(shí)例,代碼設(shè)計(jì)者confuse,編譯器設(shè)計(jì)者也覺(jué)得蠻煩。