2015-04-22 43 views
-2

傢伙PLZ檢查下面的代碼:爲什麼一個未初始化的指針在C++程序中起作用?

class Human 
{ 
public: 
    void chat(Human h) 
    { 
     cout << "human"; 
    } 

    void chat(ComputerScientist c) 
    { 
     cout << "computer"; 
    } 
}; 

class ComputerScientist : public Human 
{ 
}; 

//Main function below 
int main() 
{ 
    Human* p, p1; 
    //Uninitialized pointer above; 

    p->chat(p1); //It shows perfectly the result without ANY error! 
} 

然而,事情非常棘手,如果我做的派生類ComputerScientist一個函數,它覆蓋了人類的一個。

class Human 
{ 
public: 
    virtual void chat(Human* h) 
    { 
     cout << "about the weather"; 
    } 

    virtual void chat(ComputerScientist* c) 
    { 
     cout << "about their own computer illiteracy"; 
    } 
}; 

class ComputerScientist : public Human 
{ 
public: 
    virtual void chat(Human* h) 
    { 
     cout << " about computer games"; 
    } 

    virtual void chat(ComputerScientist* c) 
    { 
     cout << " about others’ computer  illiteracy"; 
    } 
}; 

而且我使用相同的主函數,它似乎是空指針行中的段錯誤。但爲什麼?

事情已經做出改變,在第二個例子中兩個地方:

  1. 我通過使虛擬使用的首要功能。
  2. 該函數將一個指針作爲參數。
+3

「C可以很容易地在腳中自我拍攝; C++使它更難,但是當你這樣做時,它會把你的整個腿部吹掉。」---由某人 – user3528438

+1

相關:http://stackoverflow.com/ a/29151144/332733 – Mgetz

+0

另請注意,在'human * p,p1;'中只有'p'是一個指針。如果你希望兩個都是指針,那麼使用'human * p,* p1;' – rpsml

回答

3

在第一種情況下,你的類是POD(普通舊數據)和你的聊天功能不提領/接入任何成員可變因此顯得做工好(這是一個不好的做法though-由於未定義行爲)。在virtual functions each object has vtable的情況下,需要一個有效的指針才能工作 - 從而導致故障。

這裏是你如何讓你的第一種情況下的故障,以及:

class Human 
{ 
    private: 
     int n; 
    public: 

    void chat(Human h) 
    { 
     cout << "human #" << n << endl; 
    } 

    void chat(ComputerScientist c) 
    { 
     cout << "computer"; 
    } 
}; 

class ComputerScientist:public Human{}; 

int main() 
{ 
    Human* p,p1; 
    //Uninitialized pointer above; 
    p->chat(p1);//It shows perfectly the result without ANY error! 

    return 0; 
} 
+1

注意:'因此它工作正常。'是的,這就是爲什麼它在這種情況下工作,但這並不意味着它是正確的。 OP所做的是調用一個函數,它不會以任何方式依賴於p或p1,因此編譯器會生成一個函數調用,而不會對這些變量感興趣。但它並不需要。它可能會崩潰(或其他任何東西) – deviantfan

+1

只需在這裏清楚'它工作正常'應該真的讀'它正好工作好了這一次,它可能不會下一次'。未定義的行爲是變幻莫測的事情,應該避免。 –

+0

@deviantfan:是的,這種行爲並不好,我的回答更多的是爲什麼沒有seg故障。關於編碼這不是應該如何編碼,應該在代碼評論中標記 – Sarang

4

你寫的展品未定義行爲的代碼。

  • 分段故障
  • 輸出怪異字符到屏幕上:正在經歷不確定的行爲可以編碼。
  • 因不同的優化級別和編譯器而異
  • 完全按照您的要求工作。