新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > C++中類的內(nèi)存空間大小(sizeof)分析

        C++中類的內(nèi)存空間大小(sizeof)分析

        作者: 時間:2016-12-01 來源:網(wǎng)絡(luò) 收藏
        在C語言中存在關(guān)于結(jié)構(gòu)體的存儲空間大小是比較深入的話題,其中涉及計算機的基本原理、操作系統(tǒng)等。我認為對齊是C語言中讓很多初學者都拿不準摸不透的問題,特別是在跨平臺的情況下,對齊這種問題更加的復(fù)雜多變,每一種系統(tǒng)都有自己獨特的對齊方式,在Windows中經(jīng)常是以結(jié)構(gòu)體重最大內(nèi)置類型的存儲單元的字節(jié)數(shù)作為對齊的基準,而在Linux中,所有的對齊都是以4個字節(jié)對齊。


        那么在C++中的類的內(nèi)存空間大小又有哪些特殊的問題呢?
        首先,我認為對齊肯定也是其中的問題之一,對齊主要是為了加快讀取的速度。
        關(guān)于對齊這個我認為基本上已經(jīng)是操作系統(tǒng)內(nèi)定好的,既然Linux與Windows存在差別,那么在C++的類中,關(guān)于對齊肯定也會存在一定的差別。關(guān)于對齊我認為只要記住平時使用的系統(tǒng)的對齊準則就可以了,即:在Windows中經(jīng)常是以結(jié)構(gòu)體重最大內(nèi)置類型的存儲單元的字節(jié)數(shù)作為對齊的基準,而在Linux中,所有的對齊都是以4個字節(jié)對齊。

        其次,我認為就應(yīng)該討論在基類中哪些成員占有存儲空間,那些成員不占用內(nèi)存空間?
        在C++中占存儲區(qū)間的主要是非static的數(shù)據(jù)對象,主要包括各種內(nèi)置的數(shù)據(jù)類型,類對象等,類中的函數(shù)聲明以及函數(shù)定義都不算內(nèi)存空間。但是需要注意所有的virtual函數(shù)(虛函數(shù))共享一段內(nèi)存區(qū)域,一般來說是4個字節(jié)。為什么只是包含非static數(shù)據(jù)對象呢?因為static數(shù)據(jù)并不屬于類的任何一個對象,它是類的屬性,而不是具體某一個對象的屬性,在整個內(nèi)存區(qū)域中只有一個內(nèi)存區(qū)域存儲對應(yīng)的static數(shù)據(jù),也就是所有的類對象共享這個數(shù)據(jù),所以不能算做具體某一個對象或者類型的內(nèi)存空間。
        因此可以認為基類對象的存儲空間大小為:
        非static數(shù)據(jù)成員的大小 + 4 個字節(jié)(虛函數(shù)的存儲空間)
        當然這個大小不是所有數(shù)據(jù)成員大小的疊加,而是存在一個對齊問題,具體的應(yīng)該參考相關(guān)的對齊文章。

        最后,我認為肯定要關(guān)心一下派生類的存儲空間了?
        在C++中,繼承類是一個比較有用的類,繼承使得各種類在基類的基礎(chǔ)上擴展,這時候派生類中包含了基類的信息,一般而言,在基類中存在虛函數(shù)時,派生類中繼承了基類的虛函數(shù),因此派生類中已經(jīng)繼承了派生類的虛函數(shù)。因此繼承類中不能再添加虛函數(shù)的存儲空間(因為所有的虛函數(shù)共享一塊內(nèi)存區(qū)域),而僅僅需要考慮派生類中心添加進來的非static數(shù)據(jù)成員的內(nèi)存空間大小。
        因此可以認為派生類對象的存儲空間大小為:
        基類存儲空間 + 派生類特有的非static數(shù)據(jù)成員的存儲空間

        還有一類是比較特殊的情況,如果是虛繼承的情況下,這時的存儲空間大小就會發(fā)生變化。
        基類的存儲空間 + 派生類特有的非static數(shù)據(jù)成員的存儲空間 + 每一個類的虛函數(shù)存儲空間。

        下面我采用一些例子說明上面的問題:
        對齊的問題:

        本文引用地址:http://www.104case.com/article/201612/324506.htm

        class test
        {
        public:
        test();
        private:
        int a;
        char c;
        };

        cout << sizeof(test) << endl;

        上面的代碼在linux以及windows下都會輸出8,而不是輸出5,這個是在C語言中已經(jīng)討論過的話題,但是說明對齊在C++中也是要考慮的。關(guān)于操作系統(tǒng)的差異在后面用一個統(tǒng)一的例子說明。
        虛函數(shù)問題
        為了討論虛函數(shù),我們在test類中添加一個虛析構(gòu)函數(shù),然后再測試結(jié)果。

        class test
        {
        public:
        test();
        virtual ~test();
        private:
        int a;
        char c;
        };
        cout << sizeof(test) << endl;

        這段代碼與前面的代碼沒有什么區(qū)別,只是添加了一個虛函數(shù),然后編譯調(diào)試,這時候輸出的結(jié)果12,也就是說增加了一個虛函數(shù)以后,類的數(shù)據(jù)成員增加了4個字節(jié),那么是否是每一個虛函數(shù)都占有4個字節(jié)呢?其實是不會的,在test中加入一個新的虛函數(shù)virtual void get_a_c(),這時在輸出的結(jié)果還是12,這說明所有的虛函數(shù)共享4個字節(jié)。
        static數(shù)據(jù)
        我們知道static數(shù)據(jù)是非對象的屬性,而是類的屬性,他不能算是某一個對象或者類型的存儲空間,在類定義中只能聲明,初始化只能在類外執(zhí)行,當然有例外的。這也不做分析了。具體參看后面的大例子。
        派生類的存儲空間
        派生類從基類中繼承了很多成員,自己也會增加很多的成員,由于虛函數(shù)也會被繼承下來,所以就是在派生類中不顯式定義虛函數(shù),在派生類中也會存在從基類繼承下來的虛函數(shù),因此虛函數(shù)不需要額外計算內(nèi)存空間,而只需要增加基類的非static成員數(shù)據(jù)大小。定義如下面所示,該函數(shù)會輸出20,剛好是添加的非static數(shù)據(jù)doubled的存儲空間大小。證明了上面的分析。

        class test
        {
        public:
        test();
        virtual ~test();
        virtual void get_a_c();
        private:
        int a;
        char c;
        };

        class derived_test:public test
        {
        public:
        virtual ~derived_test();
        private:
        doubled ;
        };

        cout << sizeof(derived_test) << endl;

        測試虛繼承的類的大小:

        class A
        {
        char i[3];
        public:
        virtual void a(){};
        };

        class B : public virtual A
        {
        char j[3];
        public:
        virtual void b(){}
        };

        class C: public virtual B
        {
        char k[3];
        public:
        virtual void c(){}
        };

        int main()
        {
        cout << "sizeof(A): " << sizeof(A) << endl;
        cout << "sizeof(B): " << sizeof(B) << endl;
        cout << "sizeof(C): " << sizeof(C) << endl;
        return 0;
        }

        下面采用一個比較綜合的例子說明一下操作系統(tǒng)以及各種綜合的影響分析。


        上一頁 1 2 下一頁

        關(guān)鍵詞: C++內(nèi)存空間sizeo

        評論


        相關(guān)推薦

        技術(shù)專區(qū)

        關(guān)閉
        主站蜘蛛池模板: 兰溪市| 礼泉县| 盐津县| 宁陵县| 仪征市| 武威市| 象山县| 额济纳旗| 苏尼特右旗| 林口县| 湘阴县| 石门县| 湛江市| 醴陵市| 安化县| 岱山县| 沈阳市| 无为县| 拜泉县| 锦州市| 江孜县| 富宁县| 庐江县| 宣武区| 南部县| 古田县| 勐海县| 华安县| 余庆县| 甘南县| 濮阳县| 吐鲁番市| 新蔡县| 岐山县| 五寨县| 分宜县| 梅州市| 松滋市| 沙坪坝区| 岐山县| 芷江|