2012-08-28 49 views
0

嗨,我有關於C++虛函數的1個問題...虛函數C++

class base{ 
public : 
    base() { a=5;} 
    int a; 
    virtual void print()=0; 
    int get(){return a;} 
    int get_var(){ a=5; return a;} 
}; 

int main(void){ 
    base *p; 
    cout <<"Get Call - No assign\n"; 
    cout <<"Value is :: "<<p->get()<<endl; 
    cout <<"Get Call - assign value\n"; 
    cout <<"Value is :: "<<p->get_var()<<endl; 
    return 0; 
} 

它的O/P是:: 獲取呼叫轉移 - 無指定 值是:: 5 分段錯誤

我不明白這種行爲?
我能想到的一個原因是 - 因爲base是抽象類,即沒有完全實現,所以當我正在做a = 5時它會崩潰。
但在第一次通話還我使用的是爲什麼它沒有得到墜毀有
請幫助....

+1

-1對於不良的不良格式。 –

+6

@LuchianGrigore:這不是**,**很難幫助新用戶使用formant並提示未來如何去做。 -1給你! –

+3

@DavidRodríguez-dribeas我通常這樣做,我試圖編輯自己。 *但是*不僅代碼沒有格式化,而是全部寫在一行上。 *一行,男人!* –

回答

3

根本原因:

你的指針p沒有指向任何有效的對象因此當你通過調用它的成員函數來確定崩潰時(實際上它是一個未定義行爲)。

當你聲明一個指針指向任何隨機地址時,你有責任使它指向一個有效的對象,以便能夠對指針做任何有意義的事情。

解決方案:

您需要:

base *p = new base; 

base obj; 
base *p = &obj; 

對於上述任何的工作,base必須是非抽象class.In你的榜樣base是一個抽象類(類,至少有一個純虛函數),對於這樣的類別,您不能創建任何對象(稱其構造函數爲)。
因此,要解決此問題,您需要創建派生類,該派生類從您的抽象類base派生,然後爲派生類實現純虛函數print(),從而使派生類成爲具體類而不是抽象類。然後,你可以檢查出的工作動態調度(我猜那是你的目標

class Derived:public base 
{ 
    public: 
     virtual void print() 
     { 
      //Do some prints 
     } 
}; 

int main() 
{ 
    Derived obj; 
    Base *ptr = &obj; 

    //or 

    Base *ptr2 = new Derived; 

    //.....Rest of your program as is 
} 
+2

也不是第一種方法。 – aschepler

2

你沒有初始化base *p;,因此調用它的方法是未定義行爲(在你的情況下,段錯誤) 。

另一方面,它不可能初始化它,因爲base是一個抽象類。您必須在base或派生類中提供print的定義。

1

我能想到的一個原因是 - 因爲base是抽象類,即沒有完全實現,所以當我正在做a = 5時它會崩潰。

不是,崩潰是由取消引用單位化指針p(技術上未定義的行爲)引起的。作爲base是抽象的,沒有方法來創建它的一個實例:

base b;    // Illegal 
base* p = new base; // Illegal 

,並有在發佈代碼中沒有得出具體的類。您需要從base派生並實現純虛函數print()destructor in the base class should also be virtual

0

p是未初始化的指針。所以幾乎所有的事情都是未定義行爲。

而「爲什麼不早點崩潰」的答案通常是「運氣」(好或壞,取決於您的觀點)。具有未定義行爲的程序被允許執行任何操作:似乎工作,崩潰,使您的鼠標爆炸等。