原文地址:http://hi.baidu.com/chzhao007/blog/item/e9dbc5ac1191bc034b36d6df.html
前幾天,我竟被只小鳥小覷了一下,我承認本人blog中張貼出來的代碼確實一般,所以我得在此在重審一下:本人張貼出來的代碼都不是本人最終代碼!
本人blog中到現在確實用C寫的代碼很多,但不代表本人不崇尚C++的對象編程,只不過本人現在從事的許多方面用C和彙編搞起來比較方便,所以用C寫東東比起C++來隨手。為了使本人blog闡述的東東近於完善,在此就寫下本人對C++類的一點點本質認識。在此再次重審:本人blog不代表本人現在真實水準。誰都要有點看家本事,否則在這社會上還真不好混,做為看家本事,一般是不外泄的哦。
本人在此不討論理論上什麼叫C++類(什麼類代表汽車,鴨子的不會在此文中找到),在此只在機碼層看看類到底是如何?和啟動並執行。
在這裡我先定義一個測試用的類
class one{
public:
one():a(10){}
~one(){}
void seta(int a) { this->a = a;}
int geta(void) { return a; }
void setb(int b) { this->b = b;}
int getb(void) { return b;}
private:
int a,b;
};
接下來讓我們定義一個類元素
one testone;
下面讓我們看看定義的這個testone在記憶體中佔多大
std::cout<<sizeof(testone)<<"\n"; //運行之後你會發現 testone在記憶體中只有8個位元組 就是兩個int的大小
在此我們完全可以認為 one 等同於
struct{
int a;
int b;
}one;
如果你很想耍帥的話 你可以這樣動態聲明一個類 test* one = (one *)new int(2);
現在讓我們再定義一個one元素 one testtwo; 同樣testtwo的大小也是8位元組。現在我們就有一個疑問嘍,testone與testtwo大小相同但不是同一個實體,它們是如何和 one() ~one() seta() geta()等函數聯絡到一起的?
現在讓我們在彙編級看看
testone.seta(1);
00401098 6A 01 push 1
0040109A 8D 4D EC lea ecx,[ebp-14h]
0040109D E8 72 FF FF FF call @ILT+15(one::seta) (00401014)
testtwo.seta(2);
004010A2 6A 02 push 2
004010A4 8D 4D E4 lea ecx,[ebp-1Ch]
004010A7 E8 68 FF FF FF call @ILT+15(one::seta) (00401014)
我們發現 testone和testtwo調用它們各自的seta時用到同一個地址 00401014,在此可以肯定,同一個類one定義的元素共用類one定義的方法函數。
那麼我們又可以推測出testone和testtwo的不同點是只有各自的int a\ int b 變數的地址不同了。在彙編碼中我們又發現ebp - 14h和ebp - 1ch正好相差8位元組。My Code
one testone;
one testtwo;
定義的testone和testtwo是相挨著的,所以分記憶體時testtwo會緊跟testone之後。
在此我們可以總結一下了c++類的實現,編譯器將
結構 struct{
int a;
int b;
}one;
與
一系列的函數方法
one():a(10){}
~one(){}
void seta(int a) { this->a = a;}
int geta(void) { return a; }
void setb(int b) { this->b = b;}
int getb(void) { return b;}
自動進行了捆綁。這就好比生產線,生產裝置是固定的,只是進出的零件在換罷了,而這些零件是事先處理(聲明)後與此生產線相配的一套零件。
通過以上本人對c++類本質的簡述,想畢各位可以很輕鬆的用c語言實現c++的類了吧(只要在加入結構與方法的固化就O了)。
在此本人在多述幾句,功夫高手草朩皆兵,萬物皆刃。編程注重的是思想不要固化在你所學的語言之上,要學會萬化自然。
完