2013-10-17 83 views
0

基本上我在設計一個基本的單向鏈表時,遇到了一些問題。 這裏有C++函數重載

struct Node { 
    int val; 
    Node* next; 
}; 

struct SinglyLinkedlist { 
    int size; 
    Node* head; 
    SinglyLinkedlist(); 

    const Node* Begin() const { 
    printf("const begin\n"); 
    if (size > 0) 
     return head->next; 
    } 

    Node* Begin() { 
    printf("begin\n"); 
    if (size > 0) 
     return head->next; 
    } 
}; 

我在STL容器中看到的聲明,如性病::隊列,即具有相同名稱的功能可以共存這樣,

//std::queue 
value_type& front(); 
const value_type& front() const; 

它抓住我因爲它沒有像函數重定義那樣觸發編譯失敗,例如具有相同名稱的函數,也沒有形成函數重載,例如具有相同名稱但具有不同參數類型的函數。因此,我想知道這是否是一種函數重載,我不知道或者其他類型?以及程序如何知道在運行期間調用哪個Begin(),我猜測編譯器會在上下文中檢測CONSTNESS並決定調用哪個? 我遇到的另一個問題是,如果沒有顯式重載*運算符,* Begin()例如Node *被取消引用並打印val值,基本上與Begin() - > val一樣,我想知道*運算符是否應該運行非常感謝。

int main() 
{ 
    SinglyLinkedlist l; 
    l.Push(1); 
    l.Push(2); 
    l.Push(3); 

    l.PrintList(); 
    printf("%d\n",*l.Begin()); //print out 1 same as l.Begin()->val 
} 

回答

1

是的,引用和const引用是兩種不同的類型。編譯器將根據上下文選擇const聲明。

解引用節點*爲您提供了一個struct Node,並且printf中的%d抓取了四個字節(在大多數編譯器中)並將其視爲int。如果你要改變結構中成員的順序,它會改變你的輸出。

+0

你是絕對正確的,如果我改變VAL類型爲double,最後的printf(%d)會給我垃圾值!謝謝 –

0

關於你const Node* Begin() const方法,請參閱this question

實質上,該方法保證對象不會被突變,因此可以在常量實例上調用。

所以從理論上講,這應該工作:

int main() { 
    SinglyLinkedList lst; 
    const SinglyLinkedList clst; 

    lst.Push(1); 
    lst.Push(2); 
    clst.Push(3); 
} 

這是悖論,因爲結果是列表的一個突變。但是,修改是對Nodes進行的,而不是實際的SinglyLinkedList

關於*operator:它工作正常。只有對象沒有特殊的行爲。

+0

等一下,我剛纔瞭解您關於'*'運營商的問題是什麼? – Kiruse

0

在C++中,不能過載基於返回類型,但可以在cv修飾符超載:

關於在過載 分辨率參與(13.3)的功能的信息:它的參數類型-list(8.3.5),如果 函數是類成員,則函數 本身的cv-qualifiers(如果有)以及聲明成員函數的類。 [...]

Cv-qualifiersconstvolatilemutable

所以,雖然你的兩個函數都有相同的返回類型(Node*),但它們的cv限定符是不同的,因此允許超載。

0

你需要閱讀關於const函數重載。 Const和非const函數彼此不同。例如,如果您嘗試在需要有時需要const類型的不同位置使用它,並且有時需要非const類型,則需要這兩個函數,以避免發生錯誤。

請看下面的例子:link