偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

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

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

什么是C++的空類(lèi)

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

class EmptyBase {

};

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

例如在以下代碼中EmptyBase依然是空類(lèi):

class EmptyBase {
public:

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

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

    }
    // typedef并沒(méi)有給類(lèi)增加成員或者函數(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判斷一個(gè)類(lèi)是否是空類(lèi):

#include <iostream>
class EmptyBase {

};

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

C++空類(lèi)的大小

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

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

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

為什么C++空類(lèi)的大小不是0呢?

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

空基類(lèi)優(yōu)化

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

#include <iostream>
class EmptyBase {
    // 空基類(lèi)
};

class EmptyOne: public EmptyBase{
    // 空類(lèi)1
};

class EmptyTwo: public EmptyOne{
    // 空類(lèi)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;
}

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

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

class EmptyTwo: public EmptyOne,public EmptyBase{

};

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

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

空類(lèi)存在的意義是什么

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

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

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

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

2015-12-08 14:49:13

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

2011-12-26 11:13:24

密碼

2009-08-18 17:55:20

C#操作符重載

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ù)庫(kù)MySQL主庫(kù)

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

軟件無(wú)狀態(tài)”

2011-05-24 16:20:27

虛函數(shù)

2021-04-13 09:12:45

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

2020-01-09 09:50:32

C++JavaPython

2019-02-12 11:45:05

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

2010-05-21 15:34:02

Exchange 20

2010-01-21 13:33:44

C++基類(lèi)

2013-12-04 09:46:56

Hyper-VNUMA

2018-05-17 09:46:40

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

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