重载虚函数集的部分继承

时间:2015-07-07 14:35:39

标签: c++ inheritance overloading virtual-functions

我认为我理解了继承,虚函数和函数重载,但我有一个案例,其中有关于这些特征之间的相互作用的事情让我望而却步。

假设我有一个包含重载虚函数的简单基类,以及从中派生的第二个类:

class b {
 public:
    virtual int f() { return 1; }
    virtual int f(int) { return 2; }
};


class d : public b {
 public:
    virtual int f(int) { return 3; }
};

请注意,派生类d仅覆盖其中一个重载的虚函数。

我可以实例化一个类d的对象并在其上调用f(int),没问题:

d x;
std::cout << x.f(0) << std::endl;

但是当我尝试调用0参数函数时:

std::cout << x.f() << std::endl;

失败了! gcc说&#34;没有匹配函数来调用&#39; d :: f()&#39 ;;候选者是:virtual int d :: f(int)&#34;。 clang说&#34;函数调用的参数太少,预期为1,有0;你的意思是&#39; b :: f&#39;?&#34;尽管d派生自具有0参数b方法的f(),但编译器忽略了这一点,并试图调用d&#39; s 1-改为参数方法。

我可以通过重复派生类中的0参数函数的定义来解决这个问题:

class d : public b {
 public:
    virtual int f() { return 1; }
    virtual int f(int) { return 3; }
};

或者,正如clang的错误消息所示,我可以使用一种我从未猜到的愚蠢消歧语法:

std::cout << x.b::f() << std::endl;

但我的问题是,我打破了什么规则,试图强制执行/保护/捍卫的规则是什么?我以为我试图在这里做的就是我认为继承的那种东西。

2 个答案:

答案 0 :(得分:7)

这称为名称隐藏

在派生类中声明具有相同名称的函数时,将隐藏基础中具有相同名称的所有函数。

为了获得对它们的无限制访问权限,请在派生类中添加using声明:

class d : public b {
 public:
    using b::f;
    virtual int f(int) { return 3; }
};

答案 1 :(得分:2)

除了@ TartanLlama的答案之外还有一些解释:

当编译器必须解析对Private Sub Worksheet_Change(ByVal Target As Range) Set Rng = Range("D11:D88") If Target.Count = 1 Then If Not Intersect(Target, Rng) Is Nothing Then Application.EnableEvents = False Target(1).Offset(0, 1).Value = Environ$("username") Target(1).Offset(0, 2).Value = Date Target(1).Offset(0, 3).Value = Time Application.EnableEvents = True End If End If End Sub 的调用时,它按顺序执行三项主要操作:

  1. 名称查找。在执行任何其他操作之前,编译器会搜索至少包含一个名为f的实体的范围,并生成候选列表。在这种情况下,名称查找首先查看f的范围,以查看是否至少有一个名为d的成员;如果没有,基类和封闭的命名空间 将依次考虑,一次一个,直到具有至少一个的范围 候选人被发现。但在这种情况下,编译器的第一个范围 查看已经有一个名为f的实体,然后名称查找停止。

  2. 重载分辨率。接下来,编译器执行重载决策以进行选择 候选人名单中唯一的最佳匹配。在这种情况下,参数的计数不匹配,因此失败。

  3. 辅助功能检查。最后,编译器执行可访问性检查以确定是否可以调用所选函数。

  4. Name lookup

    的参考