2013-03-06 74 views
0

誤奇怪的結果,我寫的東西愚蠢,這讓我吃驚的工作。對象的創建和綁定

class A 
{ public: 
     void print() 
     { 
      std::cout << "You can't/won't see me !!!" << std::endl; 
     } 
     A* get_me_the_current_object() 
     { 
      return this; 
     } 
}; 
int main() 
{ 
    A* abc = dynamic_cast<A*>(abc); 
    abc->print(); 
} 

這裏,A* abc = dynamic_cast<A*>(abc),我正在做一個指針,它沒有聲明dynamic_cast。但是,它的工作原理,所以我認爲上述聲明破壞爲:

A* abc; 
abc = dynamic_cast<A*>(abc); 

因此,它的工作原理。然而,在嘗試一些更奇怪的場景,如:

A* abc; 
abc->print(); 

,並進一步

A* abc = abc->get_me_the_current_object(); 
abc->print(); 

我大吃一驚,看着這些例子是如何工作的以及映射完成。
有人可以請詳細說明這些如何工作?提前致謝。

+0

反問:你爲什麼要這樣做? – leemes 2013-03-06 14:41:34

+4

這是未定義的行爲。 – juanchopanza 2013-03-06 14:43:08

+1

如果'print()'是虛擬的,那麼調用它會嘗試解除引用'abc',然後*然後*幾乎肯定會崩潰。 – 2013-03-06 14:44:53

回答

6

你所做認爲不確定的行爲和C++的錯誤意味着你應該會看到一個戲劇性的崩潰或電腦着火的常見錯誤。有時沒有任何反應這並不意味着代碼「作品」,因爲它仍然有一個錯誤,它只是症狀都沒有露面...... 尚未

但是,它的工作原理,所以我認爲,以上的語句被分解爲:

是的,你正在做的是未初始化的指針轉換爲同一類型,即無需進行轉換,所以編譯器什麼都不做。您的指針仍然是相同的類型,並且仍未初始化。

這類似於此:

int i = i; 

這是有效的,根據C++的語法,因爲i是在該點範圍,而未定義的,因爲它複製一個未初始化的對象。雖然它不太可能真正將您的計算機設置爲火線,但似乎「工作」。

可有人請詳細說明如何將這些正在努力?

技術上你訪問一個空指針,這是不確定的行爲,但由於你的成員函數實際上並不使用對象的任何成員,無效this指針不會解除引用,因此代碼「作品」 (或至少看起來像。)

這是類似的:

void function(A* that) 
{ 
    std::cout << "Hello, world!\n"; 
} 
A* p; 
function(p); 

因爲that指針不使用(如this指針未在成員函數中使用)這不一定崩​​潰,儘管它可能在實現做即使複製未初始化的指針也會導致硬件故障。在你的例子中,你的編譯器似乎不需要取消引用abc來調用非靜態成員函數,並將其作爲隱藏的this參數傳遞不會導致硬件故障,但行爲仍然未定義,即使它不「 t以明顯的方式失敗,如段錯誤。

+0

爲什麼是空指針?你首先說它是未初始化的,而不是空的。 – leemes 2013-03-06 14:44:34

+0

已經糾正 – 2013-03-06 14:47:45

+0

你聲稱有幾件事情是不合法的:'int i = i;'是無效的(因爲它涉及複製未初始化的'int'),在你的最後一個例子中,調用函數(p );'也是無效的(不管函數是什麼),因爲它涉及複製未初始化(無效)的指針。兩者都是未定義的行爲。 – 2013-03-06 15:49:48

3

abc未初始化並指向內存中未定義的位置,但是您的方法不會讀取*this中的任何內容,因此它們不會崩潰。

,他們不會崩潰的事實是幾乎可以肯定實現定義的行爲雖然。

+1

...因此不確定的行爲,因此應該避免。 – leemes 2013-03-06 14:42:52

+2

它不是「實現定義的」,因爲它具有非常具體的含義。如果它是實現定義的,那麼實現將需要記錄它們是否在這種情況下崩潰,但由於這是未定義的,它們可以做任何事情。你可能的意思是它從實現到實現都有所不同,但它從來沒有_defined_具有特定的行爲 – 2013-03-06 15:02:07