繁体   English   中英

派生类中具有相同名称但签名不同的函数

[英]Function with same name but different signature in derived class

我有一个同名的函数,但在基类和派生类中具有不同的签名。 当我尝试在继承自派生类的另一个类中使用基类的函数时,收到错误消息。 请参见以下代码:

class A
{
    public:
    void foo(string s){};
};

class B : public A
{
    public:
    int foo(int i){};
};

class C : public B
{
    public:
    void bar()
    {
        string s;
        foo(s);
    }
};

我从gcc编译器收到以下错误:

In member function `void C::bar()': no matching function for call to `C::foo(std::string&)' candidates are: int B::foo(int)

如果我删除int foo(int i){}; B类,或者如果我从foo1重命名,一切正常。

这是什么问题?

这是因为如果在您的基地之一中找到名称,名称查找就会停止。 它不会超越其他基础。 B中的功能遮盖了A中的功能。您必须在B的范围内重新声明A的功能,以便从B和C中都可以看到这两个功能:

class A
{
    public:
    void foo(string s){};
};

class B : public A
{
    public:
    int foo(int i){};
    using A::foo;
};

class C : public B
{
    public:
    void bar()
    {
        string s;
        foo(s);
    }
};

编辑:标准给出的真实描述是(从10.2 / 2开始):

以下步骤定义了在类范围C中进行名称查找的结果。首先,考虑该类及其每个基类子对象中名称的每个声明。 如果A是B的基类子对象,则一个子对象B中的成员名称f将在子对象A中隐藏成员名称f。如此被隐藏的任何声明都将被忽略。 使用声明所引入的每个声明都被视为来自C的每个子对象,该子对象的类型包含使用声明所指定的声明。96)如果结果声明集不是全部来自相同类型的子对象,或者该集合具有一个非静态成员,并且包含来自不同子对象的成员,这会产生歧义,并且程序格式错误。 否则,该设置是查找的结果。

在另一个位置(正上方)有以下说法:

对于id表达式[ 类似于“ foo”之类的名称,名称查找始于此类的范围; 对于限定ID [ 类似于“ A :: foo”,A是嵌套名称说明符 ],名称查找始于嵌套名称说明符的范围。 名称查找发生在访问控制之前(3.4,第11节)。

([...]由我提出)。 请注意,这意味着即使您在B中的foo是私有的,也仍然不会找到A中的foo(因为访问控制稍后发生)。

派生类中的函数不会覆盖基类中的函数,但是具有相同名称的函数将在基类中隐藏相同名称的其他函数。

通常,在派生类中具有与bass类中的函数同名的函数是不明智的做法,因为您所看到的通常不是期望的行为,所以它们不打算覆盖基类函数。 通常最好给不同的函数起不同的名字。

如果需要调用基本函数,则需要使用A::foo(s)来限制调用范围。 请注意,这还将同时禁用A::foo(string)任何虚函数机制。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM