C++纯虚拟方法
C++ pure virtual methods
考虑一下这个演示程序:
#include <stdio.h>
class Base
{
public:
virtual int f(int) =0;
virtual int f(){ return f(0); }
virtual ~Base(){ }
};
class Derived : public Base
{
public:
int f(int i)
{
return (10 + i);
}
};
int main(void)
{
Derived obj;
printf("%dn", obj.f(1)); // This works, and returns 11
printf("%dn", obj.f()); // Adding this line gives me the error listed below
}
这给了我以下编译错误:
virtualfunc.cpp: In function ‘int main()’:
virtualfunc.cpp:25:26: error: no matching function for call to ‘Derived::f()’
virtualfunc.cpp:15:9: note: candidate is: virtual int Derived::f(int)
我希望对obj.f()
的调用会导致对Base::obj.f()
的调用,因为派生类没有定义它,这会导致根据类Base中的定义对Derived::obj.f(0)
的调用。
我在这里做错了什么?有办法做到这一点吗?具体来说,我希望对obj.f()
的调用返回10。
(还请注意,我意识到我可以使用默认参数来解决这个问题,但这段代码只是我问题的一个简明示例,所以请不要告诉我使用默认参数。)
谢谢。
您遇到的问题与纯虚拟函数正交,并且与C++如何在类层次结构中进行名称解析有关。
当你写
obj.f();
C++试图寻找一个名为f
的函数,以便知道该调用什么。由于obj
的类型为Derived
,因此它从Derived
内部开始,并查找一个名为f
的函数。它最终找到了Derived::f(int)
,即使这个函数有一个参数,C++仍然认为这是您试图调用的方法,因此停止了查找。然后编译器会注意到您试图在没有参数的情况下调用它,从而给出有关函数调用的错误。
要解决此问题,您需要告诉C++编译器,它还需要尝试查找基类中包含的函数Base::f()
。为此,您可以更改Derived
的定义如下:
class Derived : public Base
{
public:
int f(int i)
{
return (10 + i);
}
using Base::f;
};
这行using Base::f
告诉C++,它应该将Base
中名为f
的函数视为Derived
的一部分。这样,当编译器试图查找名为f
的函数时,它会同时找到Derived::f(int)
和Base::f()
。调用将成功,因为编译器可以发现您正试图使用列出的代码调用Base::f()
。
希望这能有所帮助!
原因是,定义的f
(在Derived
中)hides
f
从Base
类起作用。解决方案是添加using
。像这样:
class Derived : public Base
{
public:
int f(int i)
{
return (10 + i);
}
// vvvvvvvvvvvvvv
using Base::f;
};
派生类中f(int)
的定义隐藏了未覆盖的Base::f
的名称。您所需要做的就是通过在派生类中写入using Base::f;
来取消隐藏它
class Derived : public Base
{
public:
using Base::f; //note this line!
int f(int i)
{
return (10 + i);
}
};
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 在模板基类中为继承类中的可选重写生成虚拟方法
- 跨 DLL 边界访问虚拟方法是否安全/可能?
- 是否可以使用基类非虚拟方法中的派生类虚拟方法?
- 如何编写 operator= 用于使用虚拟方法与非平凡成员的匿名联合
- 让编译器告诉什么确切的纯虚拟方法使结构抽象?
- 使用模板而不是虚拟方法的管道模式
- 派生类调用父类的方法,该方法调用重写的虚拟方法调用错误的方法
- 从纯虚拟类 (A) 派生的指针无法访问来自纯类 (B) 的重载方法
- 为什么调用没有正文的纯虚拟方法不会导致链接器错误?
- 出于什么目的,非虚拟方法将与C++一起使用?
- 为什么使用存储在虚拟方法表中的地址调用虚拟函数的函数会返回垃圾?
- 如何重写继承的嵌套类中存在的虚拟方法
- 私有虚拟方法有什么用?
- 派生类中纯虚拟基方法的专业化
- 基类可以声明虚拟方法但不定义它吗?仍然在派生类中定义
- googletest:测试基类具有纯虚拟方法的派生类时的核心转储
- 确保模拟的 GTest 方法覆盖虚拟方法
- 使用回调函数从构造函数调用虚拟/派生方法的替代方法?
- 如何调用孩子的方法:虚拟关键字不起作用