2010-03-18 78 views
7

即使存在聲明的隱式'this'指針,沒有數據成員的類的大小也會返回爲1個字節。不應該返回大小是4字節(在32位機器上)?我遇到了一些文章,指出爲了計算對象的大小,這個「指針」不計算在內。但我無法理解這個原因。 另外,如果任何成員函數聲明爲虛擬的,則該類的大小現在返回爲4個字節。這意味着vptr被計算用於計算對象的大小。爲什麼考慮vptr並且忽略用於計算對象大小的'this'指針?具有'this'指針的類的大小

+0

重複:http://stackoverflow.com/questions/621616/c-what-is-the-size-of-an-object-of-an-empty-class http://stackoverflow.com/questions/2362097/empty-class-in-c – 2010-03-18 07:39:18

回答

6

this指針不是類的成員。它只是一個在屬於該類的方法中用來引用當前實例的構造。

如果你有一個這樣的類:

class IntPair 
{ 
public: 
    IntPair(int a, int b) : _a(a), _b(b) { } 

    int sum() const { return _a + _b; } 

public: 
    int _a; 
    int _b; 
}; 

這個類只需要空間,爲每個實例的int兩個實例。創建實例並運行sum()方法後,將使用指向該實例的指針調用該方法,但該指針始終來自其他位置,它不會存儲在對象實例中。

例如:

IntPair *fib12 = new IntPair(89, 144); 

cout << fib12->sum(); 

注意如何在成爲this指針的變量存儲上述目的,在創建它的範圍。

你可以,事實上,總是變換的方法,如一個以上爲:

static int sum2(const IntPair* instance) 
{ 
    return instance->_a + instance->_b; 
} 

如果以上定義在類內部(以便它可以訪問私有成員),有沒有什麼區別。實際上,這個如何在場景後面實現方法;指針this只是所有成員方法的隱藏參數。

通話將成爲:

IntPair* fib12 = new IntPair(89, 144); 

cout << IntPair::sum2(fib12); 
4

「這個」不存儲在類的數據成員,它只是一個「指針」的類的實例。將其視爲傳遞給該方法的「隱藏參數」。事實上,在Win32系統中,它通常被傳入ecx寄存器(不像最初我想的那樣是eax)。

只要有一個或多個虛擬方法,應用程序就需要一種方法來存儲指向虛擬方法的指針。這稱爲vtable,對於同一個類的所有實例來說,它是相同的。由於您需要在運行時知道哪個「顯式」方法要調用哪個'虛方法'指向vtable的指針存儲在類實例中。因此,vtable指針(或vptr)需要4個字節(或64位系統上的8個字節)。

+1

我認爲這是通過'ecx'傳遞的。 – Blindy 2010-03-18 08:05:39

+0

糟糕,是的,你是對的。 eax用於返回值。除了sizeof()返回的是字節數,而不是bits,sizeof(int *)和sizeof(int **)不能不同,(我編輯的帖子) – Patrick 2010-03-18 17:19:53

2

該指針不存儲在對象內部。沒有必要這樣做。您已經有一個指針或一個對象來調用這些函數。至於1的大小,C++標準要求distict對象具有不同的地址。

-1

指針的大小始終是需要存儲在內存中的指針類型的大小。

例如,如果一個int的存儲器地址是32位上的64位體系結構,然後

INT A = 10; int * b =&a; (b); // 32 sizeof(& b); 64

+0

。 – PlasmaHH 2012-06-01 08:24:02