C++继承类中的函数重载问题

61

这可能是一个初学者问题,抱歉。最近我在尝试使用C++中的一些高级内容——函数重载和继承时,遇到了一个奇怪的问题。

我将展示一个简单的例子来演示这个问题;

有两个类,classAclassB,如下所示:

class classA{
    public:
        void func(char[]){};    
};

class classB:public classA{ 
    public:
        void func(int){};
};

据我所知,classB现在应该拥有两个func(..)函数,由于参数不同而被重载。

但是当在主方法中尝试这样做时;

int main(){
    int a;
    char b[20];
    classB objB;
    objB.func(a);    //this one is fine
    objB.func(b);    //here's the problem!
    return 0;
}

由于超类classA中的方法void func(char[]){};在派生类classB中不可见,因此会出现错误。

我该怎么解决这个问题呢?难道这就是C++中重载的工作原理吗?虽然我是C++新手,但在Java中,我知道可以利用这样的东西。

尽管我已经找到了这个线程,它也提出了类似的问题,但我认为这两种情况是不同的。

5个回答

79

你需要的只是一个 using

class classB:public classA{ 
    public:
        using classA::func;
        void func(int){};
};

因为已经在派生类中找到了一个函数func,所以它不会搜索基类。 using语句将另一个重载引入相同的作用域,使其能够参与重载决策。


2020年现在有更好的替代方案吗? - VimNing
@Raining,不会有的,我认为这种可能性很小。我不确定你所说的替代方案是什么,而不是更改名称查找,这并不是一个吸引人的前景。如果你能称之为替代方案的话,你可以在基类中提供所有重载,并一次性将它们带入作用域。这种技术在使用可变参数模板时非常有用。除此之外,在如此一般的层面上很难说——也许在更狭窄的上下文中有一些新的东西是有用的。也许你可以考虑组合而非继承作为一种普遍的替代方案。 - chris

12

1
谢谢你的回答和链接。我想知道C++的人是否有意保留这个东西。有什么好处吗?对我来说,这似乎破坏了继承的概念,不是吗? - Anubis
@Sumudu:我可以给你一个绝对正确的想法,并且我认为7年后你已经不再关心了:(来自语言规范)这是因为我们不希望基类的更改影响派生类。 - VimNing

3

如果您在派生类中覆盖了一个函数的变体,那么您需要覆盖所有变体。您可以使用JLledo建议的方法,或者编写派生类中函数的变体,该变体仅调用具有相同签名的基类函数。

class classA{
    public:
        void func(char[]){};    
};

class classB:public classA{ 
    public:
        void func(int){};
        void func(char[]){};
};

void classB:func(char[] ch)
{
    classA::func(ch);
}

1
所提出的解决方案会带来维护上的麻烦。在派生类中注入using A::func需要软件重新架构对派生类中使用条款的敏感性,也就是说,维护人员不仅必须更改基类本身,还必须更改派生类。假设我们从base<-derived1转换到base<-derived2<-derived1。现在,一个使用条款using base::func必须更改为using derived2::func,迫使考虑使用条款并增加维护成本。虽然这在C++标准化工作中已被使用了相当长的时间,但这个想法似乎是不明智的。它打扰了继承的概念。以上仅为个人看法。

-5

你必须传递 int 类型的参数

objB.func(b);    //here's the problem!

因为它已经被重载了带有 int 参数的函数


你可以尝试并提供更详细的答案。 - easwee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接