2010-06-04 110 views
4

我有下面的代碼是似乎是導致死循環:這個程序爲什麼會掛起?

struct X 
{ 
    void my_func(int) { std::cout << "Converted to int" << std::endl; } 
}; 

struct X2 : X 
{ 
    void my_func(char value) { my_func(value); } 
}; 

什麼是它的問題?

+3

這裏沒有程序,只有兩個類定義。它不,也不能掛起。事實上,它無法運行。發佈您正在嘗試運行的實際代碼。 – AnT 2010-06-04 06:10:40

+1

我們大多數人都能夠填補空白。只是在說'... – 2010-06-04 08:14:36

+0

@Igor Zevaka:當然可以。但在10個「填空」的案例中,有9個對無意義的問題產生了無用的答案。我希望這個證明是在10分之一的時候是有效的。 – AnT 2010-06-04 17:31:50

回答

10

第二位是無限遞歸:

struct X2 : X 
{ 
    void my_func(char value) { my_func(value); } //calls itself over and over again 
}; 

前綴my_func與基類的名字,你會沒事的

struct X2 : X 
{ 
    void my_func(char value) { X::my_func(value); } 
}; 

編輯剛剛意識到基類 my_func「簽名是不同的。 C++編譯器會靜態解析函數重載,這意味着它會選擇與參數類型最匹配的函數,這就是爲什麼它會調用過載。

例如:

char cChar = 'a'; 

myfunc(cChar); 

void myfunc(char a){} //<-- this one is called 
void myfunc(int a){} 

int iInt = 1; 

myfunc(iInt); 

void myfunc(char a){} 
void myfunc(int a){} //<-- this one is called 

由於查爾斯貝利。以上代碼不適用於這種情況,因爲X2my_func隱藏了基類的my_func。這留下了唯一的解決方案來用類名限定函數。

+0

Thanx。我認爲'my_func'尚未定義,並且應該調用'X :: my_func'。 – 2010-06-04 05:55:52

+0

@zilgo:它沒有被定義,但它被聲明。這就是你需要的一切。 – GManNickG 2010-06-04 05:57:58

+1

在派生類中,具有相同名稱但具有不同簽名的任何函數都將隱藏相同名稱的基類函數。這意味着在'X2'的成員函數中沒有限定'my_func' _always_引用'X2 :: my_func',而不是'X :: my_func'。這裏沒有「最佳匹配」。發佈的「例如:」具有誤導性,因爲它在這種情況下根本不適用。 – 2010-06-04 07:33:10

2
void my_func(char value) { my_func(value); } 

你傳遞的value這是char所以它解析爲調用同樣的方法與接受char參數。它變成了一個無限循環。

2
void my_func(char value) { my_func(value); } 

就在那裏,你已經寫了一個沒有基本情況的遞歸函數。我不太瞭解C++,但是你需要以某種方式指定你想調用X的my_func,而不是X2(我假設這就是你想要做的。)

編輯:要修復它,您需要將值轉換爲int

+2

轉換爲參數的「int」不會有幫助。派生類中的'my_func'隱藏了基類'my_func'。需要顯式限定'my_func'。 – 2010-06-04 07:34:38

+0

它是不是超載它,不隱藏它? – Bwmat 2010-06-04 18:49:42

0

程序進入無限循環。 my_func()調用它自己,並且沒有條件退出它。

0

你的調用my_func(value)是遞歸的。你的意思是超:: my_func(價值)?

0

您需要顯式調用基類的功能,即:

struct X 
{ 
    void my_func(int) { std::cout << "Converted to int" << std::endl; } 
}; 

struct X2 : X 
{ 
    void my_func(char value) { X:my_func(value); } 
}; 

默認情況下,編譯器使用功能相同的類中如果存在的話,因爲沒有辦法爲它知道是哪一個你真的想使用。通過在派生類的方法中指定BaseClass::Function,編譯器將顯式創建對該基類方法的調用,即使您已被覆蓋。