電話外包接單平臺seo網(wǎng)站優(yōu)化網(wǎng)站編輯招聘
以下內(nèi)容源于C語言中文網(wǎng)的學(xué)習(xí)與整理,非原創(chuàng),如有侵權(quán)請告知刪除。
對象被創(chuàng)建時會在棧區(qū)或者堆區(qū)分配內(nèi)存。我們直觀的認(rèn)識是,如果創(chuàng)建了 10 個對象,就要分別為這 10 個對象的成員變量和成員函數(shù)分配內(nèi)存,如下圖所示:
不同對象的成員變量的值可能不同,因此需要單獨分配內(nèi)存來存儲。
但是不同對象的成員函數(shù)的代碼是一樣的,上面的內(nèi)存模型保存了 10 份相同的代碼片段,會浪費不少空間。我們可以將這些代碼片段壓縮成一份,事實上編譯器也是這樣做的:編譯器將成員變量和成員函數(shù)分開存儲,即分別為每個對象的成員變量分配內(nèi)存,但是所有對象都共享同一段函數(shù)代碼。如下圖所示:
成員變量在堆區(qū)或棧區(qū)分配內(nèi)存,成員函數(shù)在代碼區(qū)分配內(nèi)存。
【示例】使用 sizeof 獲取對象所占內(nèi)存的大小:
#include <iostream>
using namespace std;class Student{
private:char *m_name;int m_age;float m_score;
public:void setname(char *name);void setage(int age);void setscore(float score);void show();
};void Student::setname(char *name){m_name = name;
}
void Student::setage(int age){m_age = age;
}
void Student::setscore(float score){m_score = score;
}
void Student::show(){cout<<m_name<<"的年齡是"<<m_age<<",成績是"<<m_score<<endl;
}int main(){//在棧上創(chuàng)建對象Student stu;cout<<sizeof(stu)<<endl;//在堆上創(chuàng)建對象Student *pstu = new Student();cout<<sizeof(*pstu)<<endl;//類的大小cout<<sizeof(Student)<<endl;return 0;
}
運行結(jié)果:
12
12
12
Student 類包含三個成員變量,它們的類型分別是 char *、int、float,都占用 4 個字節(jié)的內(nèi)存,加起來共占用 12 個字節(jié)的內(nèi)存。通過 sizeof 求得的結(jié)果等于 12,恰好說明對象所占用的內(nèi)存僅僅包含了成員變量。
類是一種復(fù)雜的數(shù)據(jù)類型,也可以使用 sizeof 求得該類型的大小。從運行結(jié)果可以看出,在計算類這種類型的大小時,只計算成員變量的大小,并沒有把成員函數(shù)也包含在內(nèi)。也就是說,對象的大小只受成員變量的影響,和成員函數(shù)沒有關(guān)系。
假設(shè) stu 的起始地址為 0X1000,那么該對象的內(nèi)存分布如下圖所示:
m_name、m_age、m_score 按照聲明的順序依次排列,和結(jié)構(gòu)體非常類似,也會有內(nèi)存對齊的問題。比如,如果修改類的成員變量如下,則該類型的大小變?yōu)?6。
//省略其他代碼
private:char *m_name;//指針變量占4字節(jié)char m_char;//字符變量原本只占1個字節(jié),但內(nèi)存對齊,這里占4字節(jié)int m_age;//int類型變量占4字節(jié)float m_score;//float類型變量占4字節(jié)
//省略其他代碼