上面的**會列印「a」。
c++ 類指標定義的時候沒有初始化的時候,居然可以安全的呼叫類內部的成員函式而不出錯。
在網上查了一下:
初始化為null的類指標可以安全的呼叫不涉及類成員變數的類成員函式而不出錯,但是如果類成員函式中呼叫了類成員變數則會出錯,既然賦值為null的情況都可以使用,那麼自然不初始化的類指標同樣滿足這類情況。
假設現在有乙個簡單的類定義如下:
class test
int get()
test():a(1),b(2){}
public:
int a,b;
};而之後編譯器會自動將這個類轉換成:
class test
;void _test_func(test * this);
int _test_get(test* this);
........
類中的函式被編譯器靜態編譯了,所有非虛函式(虛函式呢?別急,待會會解釋到)都可以呼叫,因為函式位址編譯期間已經確定。我們知道,類中的成員函式都是通過this指標呼叫成員變數的,編譯器會將this指標作為預設引數傳給類成員函式的,如myclass.function(int a,int b) --> function(&myclass,int a,int b)
新增main函式如下:
int main()
執行結果如上,沒有呼叫成員變數的func()函式正確執行,呼叫了成員變數的get()函式錯誤。兩者其實都傳入了空的this指標,前者沒出錯僅僅是因為沒有呼叫this指標,而後者呼叫了。(此時p-func()和p->get()等同於func(null),get(null)......)是物件指標為null,而呼叫成員函式的時候,函式位址是編譯期間確定的,成員函式不通過物件指標(也即當前的p指標)去呼叫,物件指標僅僅作為引數傳入函式然後去呼叫成員變數。
好現在問題來了,如果是虛函式呢,因為虛函式要通過this指標計算vptr,然後找到vtable,然後dispatch。因為this指標為空,所以在找vtable時候就會coredump了。總之這類情況下,一切呼叫了this指標的函式都會出錯,而完全不呼叫this指標的成員函式則沒問題。
總結:任何時候定義指標的時候一定要初始化,這是良好的習慣,這個問題最初是由於當時寫程式疏忽造成的,然而錯有錯著居然編譯通過,所以當時一直沒發現這個手誤,現在追本溯源也算是對c++的內部機制有了更深的了解,不過也提示自己不能有僥倖心理,一定要養成良好的程式設計習慣,不管對於自己還是對於以後合作的夥伴都是一件好事。
C 類指標初始化
上面 的 會列印 a c 類指標定義的時候沒有初始化的時候,居然可以安全的呼叫類內部的成員函式而不出錯。在網上查了一下 初始化為null的類指標可以安全的呼叫不涉及類成員變數的類成員函式而不出錯,但是如果類成員函式中呼叫了類成員變數則會出錯,既然賦值為null的情況都可以使用,那麼自然不初始化的類指...
初始化指標
includeusing namespace std int main nullptr 是 c 新標準引入的特性,visual c 2010 編譯器支援它。過去已經使用0或 null 編譯器將用 0代替此巨集 來初始化指標,當然它們現在仍然可以使用。但是,使用 nullptr 初始化指標要好得多。因...
C 類變數初始化
c 類變數初始化 c 為中類物件的構造順序是這樣的 1.分配記憶體,呼叫建構函式時,隱式 顯示的初始化各資料成員 2.進入建構函式後在建構函式中執行一般計算 c 類中變數的初始化 1.初始化列表 csomeclass csomeclass x 0 y 1 const常量定義必須初始化,且必須使用初始...