引用类型转换中的c++虚函数
C++ virtual function in type casting of reference
我对虚函数和引用有一个疑问。这是我准备面试时遇到的一个难题。我在谷歌上搜索了一段时间,但没有看到确切的情况。
代码如下:
class A{
public:
virtual void foo() {cout << "A::foo" << endl;}
};
class B: public A{
public:
void foo() {cout << "B::foo" << endl;}
};
class C: public B{
public:
void foo() {cout << "C::foo" << endl;}
};
int main(void){
C c;
B *q;
q = &c; q->foo();
return 0;
}
我认为输出将是B::foo,但答案实际上是C::foo。有人能告诉我为什么虚表不选择B的实现吗?由于
如果foo
不是虚指针,则调用的函数将基于指针的类型,并调用B::foo()
。
由于foo
在基类中被定义为虚的,因此它在所有派生类中都保持虚的。在这种情况下,调用的函数是基于指向的对象的类型,而不是指针的类型。由于指向的对象是C
,因此调用的函数是C::foo()
。
foo
在B
中是虚函数,因为它覆盖了基类中的虚函数,即使它没有显式声明为virtual
。
通过q->foo()
调用的对象的最派生类型是C
,而C
对foo
的最终覆盖(带有void foo()
签名)是C::foo
,因此这就是被调用的函数
因为q
指向一个C
对象,并且它的虚函数表包含一个虚函数foo
。记住,在类中声明的任何虚函数在任何派生类中都是虚的。这是使用基类来访问派生类的方法。
韩文:
一旦使用了虚表——在这种情况下是由A::foo
的virtual
声明强制的——声明什么类型并不重要,它总是调用最特定的方法的方法——在这种情况下是C::foo
。
谁能告诉我为什么虚表不选择B的实现?
这就是使用虚函数的全部意义所在,因此通过基类指针调用被重写的方法仍然会从派生类调用该方法。
q
是B *
类型的,但是它指向一个C
对象。因此,当您调用虚函数foo()
时,将调用C::foo()
实现。
尽管foo()
在B
和C
中没有标记为virtual
,但它仍然是一个虚函数,因为它在A
中是这样声明的。
如果你想要调用B::foo()
,你需要显式地调用它。
q->B::foo();
foo()
是虚函数,这意味着调用q
实际指向的实例的类中定义的版本,而不是指针类型中类中定义的版本。
请记住,一旦成员函数在类层次结构的某个地方被标记为虚函数,它就是虚函数,也就是说,不需要在类B和C中再次显式地将函数标记为虚函数,因为在类a中已经这样做了。
- "error: no matching function for call to"构造函数错误
- 什么时候调用组成单元对象的析构函数
- 继承函数的重载解析
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- C++模板来检查友元函数的存在
- 递归函数计算序列中的平方和(并输出过程)
- 对RValue对象调用的LValue ref限定成员函数
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 为什么使用 "this" 指针调用派生成员函数?
- 将对象数组的引用传递给函数
- 函数调用中参数的顺序重要吗
- 函数向量_指针有不同的原型,我可以构建一个吗
- 使用不带参数的函数访问结构元素
- 代码在main()中运行,但在函数中出现错误
- 内置函数可查看CPP中的成员变量
- 如何获取std::result_of函数的返回类型
- 如何在c++中为模板函数实例创建快捷方式
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗