自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

C++空類的那點(diǎn)事兒

開發(fā) 前端
在C++標(biāo)準(zhǔn)庫中,五種迭代器類別都有對應(yīng)的空類。這些空類用于標(biāo)識迭代器的類別,并通過模板特化來實(shí)現(xiàn)對不同類型迭代器的特殊處理。

什么是C++的空類

顧名思義,空類就是指哪些不包含成員變量的類。例如以下這個就是一個空類:

class EmptyBase {

};

既然如此,那么是不是說空類的內(nèi)部一定不會其他代碼呢?不是的,空類內(nèi)部也可以包含其他東西,例如:構(gòu)造函數(shù)、析構(gòu)函數(shù)、靜態(tài)成員變量、靜態(tài)函數(shù)、成員函數(shù)、typedef語句等。

例如在以下代碼中EmptyBase依然是空類:

class EmptyBase {
public:

    // 構(gòu)造函數(shù)
    EmptyBase(){

    }
    // 析構(gòu)函數(shù)
    ~EmptyBase(){

    }
    // typedef并沒有給類增加成員或者函數(shù)

    typedef int INT_NUM;
    
    // 不涉及到內(nèi)部成員變量的內(nèi)部函數(shù)
    void set(int a){

    }
    // 靜態(tài)函數(shù)
    static void setStr(const std::string& s){

    }

    // 靜態(tài)變量
    static std::string str;
};

在C++11之后我們可以使用std::is_empty判斷一個類是否是空類:

#include <iostream>
class EmptyBase {

};

int main() {
    
    auto aa = std::is_empty<EmptyBase>::value;
    std::cout << "是否是空類:" << aa << std::endl;
    return 0;
}

C++空類的大小

有以下計算空類大小的代碼,你認(rèn)為輸出結(jié)果是多少?

#include <iostream>
class EmptyClass {
    // 空類
};
int main(int argc, char* argv[]) {
    std::cout << "sizeof(EmptyClass): " << sizeof(EmptyClass) << std::endl;
    return 0;
}

即使是空類,其大小也不會為0。在許多平臺上,空類的大小為1;而在某些對于對齊(alignment)要求更嚴(yán)格系統(tǒng)上,空類的大小可能是另一個數(shù)(通常是4)。

為什么C++空類的大小不是0呢?

C++的設(shè)計者們不允許類的大小為0,因?yàn)槊總€對象都必須具有唯一的地址,特別是在涉及到取址和指針計算時,如果一個類的大小是0,那么指針的一切將會失效。 試想一下如果空類的大小為0,那么由空類它們構(gòu)成的數(shù)組,其大小必然也是0,這會導(dǎo)致指針運(yùn)算中普遍使用的性質(zhì)失效。

空基類優(yōu)化

C++標(biāo)準(zhǔn)規(guī)定,當(dāng)空類作為基類時,只要不會與同一類型的另一個對象或子對象分配在同一地址,就不需為其分配任何空間。

#include <iostream>
class EmptyBase {
    // 空基類
};

class EmptyOne: public EmptyBase{
    // 空類1
};

class EmptyTwo: public EmptyOne{
    // 空類2
};

int main(int argc, char* argv[]) {
    std::cout << "sizeof(EmptyBase): " << sizeof(EmptyBase) << std::endl;
    std::cout << "sizeof(EmptyOne): " << sizeof(EmptyOne) << std::endl;
    std::cout << "sizeof(EmptyTwo): " << sizeof(EmptyTwo) << std::endl;
    return 0;
}

如果編譯器支持空基類優(yōu)化,上述程序所有的輸出結(jié)果相同(一般是1),但均不為0。

我們修改一下代碼,將EmptyTwo改為多繼承,那么EmptyTwo還是空類嗎?

class EmptyTwo: public EmptyOne,public EmptyBase{

};

答案是在多繼承狀態(tài)的EmptyTwo已經(jīng)不是空類了, 雖然EmptyTwo和它的基類都沒有任何成員。不過,EmptyTwo的基類EmptyOne和EmptyBase不能分配到同一地址空間, 否則EmptyTwo的基類EmptyBase會和EmptyOne的基類EmptyBase撞在同一地址空間上。換句話說,兩個相同類型的子對象偏移量相同,這是C++對象布局規(guī)則不允許的。

對空基類優(yōu)化進(jìn)行限制的根本原因在于,我們需要能比較兩個指針是否指向同一對象。 由于指針幾乎總是用地址作內(nèi)部表示,所以我們必須保證兩個不同的地址(即兩個不同的指針值)對應(yīng)兩個不同的對象。 雖然這種約束看起來并不非常重要,但是在實(shí)際應(yīng)用中的許多類都是繼承自一組定義公共typedefs的基類,當(dāng)這些類作為子對象出現(xiàn)在同一對象中時,問題就凸現(xiàn)出來了,此時優(yōu)化應(yīng)被禁止。

空類存在的意義是什么

盡管在面向?qū)ο缶幊讨?,空類看起來可能有些多余,但是它們存確有它們的用途。

空類是一種有著潛在應(yīng)用價值的編程技巧,例如空類可以被用于多種編程模式和設(shè)計模式中,它還可以作為數(shù)據(jù)類型的標(biāo)記,用于在編譯時實(shí)現(xiàn)條件編譯。 空類也可以作為接口占位符,用于后續(xù)的繼承實(shí)現(xiàn)或者后續(xù)擴(kuò)展等。空類也在模板編程和元編程等高級編程技術(shù)中也發(fā)揮重要作用。

例如在C++標(biāo)準(zhǔn)庫中,五種迭代器類別都有對應(yīng)的空類。這些空類用于標(biāo)識迭代器的類別,并通過模板特化來實(shí)現(xiàn)對不同類型迭代器的特殊處理,如圖:

責(zé)任編輯:趙寧寧 來源: 思想覺悟
相關(guān)推薦

2009-08-18 17:55:20

C#操作符重載

2011-12-26 11:13:24

密碼

2015-12-08 14:49:13

SDN軟件定義網(wǎng)絡(luò)

2020-01-03 07:57:39

UDPTCP網(wǎng)絡(luò)協(xié)議

2012-04-17 11:21:50

Java

2022-05-26 15:30:21

Spring AOP框架

2022-05-26 09:03:39

AOP編程

2017-09-12 08:03:29

數(shù)據(jù)庫MySQL主庫

2013-12-26 13:35:39

2012-03-12 21:23:47

Windows pho

2013-09-17 10:37:03

AOPAOP教程理解AOP

2018-03-30 16:03:04

軟件無狀態(tài)”

2011-05-24 16:20:27

虛函數(shù)

2020-01-09 09:50:32

C++JavaPython

2021-04-13 09:12:45

網(wǎng)絡(luò)設(shè)備無線路由器交換機(jī)

2019-02-12 11:45:05

Java數(shù)據(jù)庫開發(fā)

2010-01-21 13:33:44

C++基類

2010-05-21 15:34:02

Exchange 20

2010-01-15 18:35:25

C++的類

2018-05-17 09:46:40

apachenginx阻塞
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號