2017-08-12 109 views
0

我在面向對象的方法和C++編程的新手,以及: 我的問題是:如何能未實例化的任何對象的類指針可以調用的成員函數那個班。下面是我今天調用非靜態成員函數,而無需創建一個實例

#include <iostream> 


class Base{ 
public: 
    Base(){ 
      std::cout << "Base C-tor is called " << std::endl; 
    } 
    void fun(){ 
      std::cout << "Base fun() is called " << std::endl; 
    } 
    void sorrow(){ 
      std::cout << "Base Sorrow is called " << std::endl; 
    } 
    ~Base(){ 
      std::cout << "Base D-tor is called " << std::endl; 
    } 
}; 


int main(){ 

Base *b1; 
b1->fun(); 
b1->sorrow(); 
} 

下面試圖運行的代碼是這段代碼的輸出:

Base fun() is called 
Base Sorrow is called 
+3

這是不確定的行爲,而不是_working code_。 – user0042

+0

其中不從未訪問任何數據成員中的對象的函數應該是靜態的。你所展示的設計是否有用也是有問題的。編寫像函數一樣的C並添加類並不是面向對象的編程。訪問未初始化的指針只是未定義的行爲。編譯器優化未使用的指針離開並不意味着你寫有效的代碼在所有。 – Klaus

回答

2

儘管調用未定義的行爲,你的代碼會因爲這樣的工作的外觀編譯器調用非虛擬成員函數。在您的fun()sorrow()成員函數情況下,進行的情況下,不訪問,因此函數完成,就好像它的工作(即使它的調用仍然無效)。

如果你宣佈你的功能virtual,崩潰的可能性將大大上升(雖然你不能保證與未定義行爲的任​​何東西):

virtual void fun(){ 
     std::cout << "Base fun() is called " << std::endl; 
} 
virtual void sorrow(){ 
     std::cout << "Base Sorrow is called " << std::endl; 
} 

調用虛函數需要訪問類的實例用於該功能的位置。由於指針未初始化,代碼很可能會崩潰。

+0

感謝您的回答。是虛擬的,它崩潰了。關於訪問對象,我試圖在fun()中指定一些變量的值,這是該類的私有成員。它打印了我分配給它的正確值。 –

+0

@RahulSaraswat雖然所有的UB都是同樣無效的,但它們造成崩潰的概率是不同的。通常,任何與執行CPU指令(如函數調用)有關的任何事情,比讀取或寫入垃圾內存位置(當您使用未初始化的指針訪問私有變量時發生的情況)都更有可能導致崩潰。 – dasblinkenlight

相關問題