提问人:Igor 提问时间:1/4/2009 最后编辑:ks1322Igor 更新时间:2/21/2023 访问量:50115
在派生类中找不到同名但签名不同的函数
Function with same name but different signature in derived class not found
问:
我有一个同名的函数,但在基类和派生类中具有不同的签名。当我尝试在另一个继承自派生的类中使用基类的函数时,我收到一个错误。请参见以下代码:
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 中名称查找的结果。首先,每个声明 考虑类及其每个基类子对象中的名称。一个子中的成员名称 f 如果 A 是 B 的基类子对象,则对象 B 在子对象 A 中隐藏成员名称 f。任何声明 如此隐藏的东西被排除在考虑之外。这些声明中的每一个都是由 using-declaration 被认为是来自 C 的每个子对象,该子对象属于包含声明的类型 96) 如果生成的声明集并非全部来自子对象 相同类型的,或者集合具有非静态成员并包含来自不同子对象的成员,则有 模棱两可,程序格式不正确。否则,该集是查找的结果。
它在另一个地方(就在它上面)有如下要说:
对于 id-expression [类似 “foo”],名称查找从 this 的类范围开始;对于 qualified-id [类似于 “A::foo”,A 是嵌套名称说明符],名称查找在嵌套名称说明符的作用域中开始。名称查找在访问控制之前进行(3.4,第 11 条)。
([...]由我提出)。请注意,这意味着即使您在 B 中的 foo 是私有的,仍然找不到 A 中的 foo(因为访问控制稍后发生)。
评论
void A::foo(class basic_string<char,char_traits<char>,allocator<char> >)' in
派生类中的函数不重写基类中的函数,但具有相同的名称,将隐藏基类中同名的其他函数。
通常认为,在派生类中具有与 bass 类中的函数同名的函数是不好的做法,这些函数并不打算覆盖基类函数,因为您所看到的通常不是理想的行为。通常最好为不同的函数提供不同的名称。
如果需要调用基函数,则需要使用 来限定调用范围。请注意,这也将同时禁用任何虚拟功能机制。A::foo(s)
A::foo(string)
评论
Functions in derived classes which don't override functions in base classes but which have the same name will hide other functions of the same name in the base class.
同名和签名?我有点困惑,因为我发现有几篇文章认为这是 C++ 的方法覆盖版本(例如,C++ 中的 g4g 函数覆盖
评论