调用非虚函数的虚函数
Virtual function calling a non-virtual function
我写了以下一段代码来测试我对虚拟继承的理解。显然,我仍然没有完全理解它。这是我的代码(后面跟着我的问题(:
#include <iostream>
#include <vector>
using namespace std;
class Foo
{
public:
virtual void foo();
void foo2();
};
void Foo::foo()
{
cout << "In FOO - foo 1" << endl;
foo2();
}
void Foo::foo2()
{
cout << "In FOO - foo 2" << endl;
}
class Bar : public Foo
{
public:
void foo();
void foo2();
};
void Bar::foo()
{
cout << "In BAR - foo 1" << endl;
foo2();
}
void Bar::foo2()
{
cout << "In BAR - foo 2" << endl;
}
int main()
{
Foo* f = new Foo;
f->foo();
Foo* b = new Bar;
b->foo();
return 0;
}
这是我的理解:
指针 f 指向基类 Foo,f->foo()
调用基类中的foo()
,基类又调用基类中的foo2()
。
指针 b 是基类指针,但指向派生类 Bar 的对象。现在,由于foo()
是一个虚函数,因此它调用派生类foo()
。现在(派生类的(foo()
调用foo2()
。由于foo2()
不是虚函数,我期待基类foo2()
被调用。但是,我看到foo2()
派生类都被调用了。
所以,我期待这个输出:
In FOO - foo 1
In FOO - foo 2
In BAR - foo 1
In FOO - foo 2
但得到了这个:
In FOO - foo 1
In FOO - foo 2
In BAR - foo 1
In BAR - foo 2
为什么会这样?据我了解,vtable 将有一个仅用于foo()
的条目,而不是用于foo2()
的条目。那么,如何调用派生类foo2()
呢?
这是我的第一篇文章。如果我违反了任何发布准则,请原谅我。提前感谢!
在Bar::foo()
中,您正在调用foo2()
。 这真的相当于叫this->foo2()
。 this
的类型是Bar
,所以这实际上等同于:
void Bar::foo()
{
Bar *bar = this;
bar->foo2();
}
因此,此时不涉及多态性;调用解析为在编译时Bar::foo2
,而不是在运行时动态
因为 Bars foo 就是所谓的 foo2,在那个阶段它知道它是一个 Bar....
再试一次,除了直接在 main 中调用 foo2 而不是 foo 调用 foo2
int main()
{
Foo* f = new Foo;
f->foo();
f->foo2();
Foo* b = new Bar;
b->foo();
b->foo2();
return 0;
}
如何调用派生类的 FOO2((?
你希望 Bar::foo2 永远不会被调用。然后,您的问题可以重新表述为:"为什么Bar::foo2的目的是,如果有的话?
其目的是在处理 Bar 对象时调用。每当调用 foo2 时,都会调用 Bar 对象的 foo2。
只有对于 foo 对象,Foo::bar2 是否是虚拟的才重要。 如果您直接处理派生类对象,继承永远不会强制您在基类中使用具有相同签名的函数。(在这件事上,继承规则以不同的方式工作会导致太多不愉快的意外。
你所做的本质上是隐藏。通过在 Bar 中创建具有相同签名的函数,您将非虚函数隐藏在基类 Foo 中。这通常是一个糟糕的设计,因为它不必要地复杂 - 最好为不同的东西选择不同的名称,以避免隐藏。隐藏很少是有意识的良好设计的一部分。
void Bar::foo()
{
cout << "In BAR - foo 1" << endl;
foo2();
}
这是因为Bar::foo2()
是foo()
调用的foo2()
。 Bar::foo2()
是Bar::foo()
的本地,具有优先权。这只是来自Bar::foo2()
的静态调度.
如果您期望的行为是您真正想要的,则可以通过指定其范围来选择该方法,如下所示:
void Bar::foo()
{
cout << "In BAR - foo 1" << endl;
Foo::foo2();
}
所以这真的与动态调度无关。
- 函数调用中参数的顺序重要吗
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 变量没有改变?通过向量的函数调用
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数
- 我知道函数调用中存在歧义.有没有办法调用foo()函数
- 模板函数调用
- 获取从C++中同一类中的构造函数调用的方法返回的值
- 析构函数调用
- 成员函数调用和C++对象模型
- 使用共享指针的函数调用,其对象应为 const
- C++:编译时检查匹配的函数调用对?
- 函数调用C++中的参数太少
- 来自 DLL 的函数调用 [表观调用的括号前面的表达式必须具有(指向-)函数类型]
- 返回指向对象的指针的函数调用是否为 prvalue?
- C++ 如何重载 [] 运算符并进行函数调用
- 代码的效率. 转到和函数调用
- 是同一作用域的函数部分中的函数调用
- 如何封装一个函数,以便它只能由同一类中的一个其他函数调用?
- 类型擦除的std::function与虚拟函数调用的开销