2013-10-17 46 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