如何理解最终覆盖器返回的类型被隐式转换为被调用的覆盖函数的返回类型?

约翰

根据文件,它说[强调我的]:

当进行虚函数调用时,最终覆盖器返回的类型会隐式转换为被调用的覆盖函数的返回类型

如何以正确的方式理解这一点?

根据下面演示代码的输出,最终覆盖器返回的类型似乎取决于实例的静态类型(将在其上调用成员函数)。

如果我错过了什么,请告诉我。

这是演示代码片段

#include<iostream>
#include<typeinfo>

#define print() std::cout << __PRETTY_FUNCTION__ << std::endl;

class B {};
 
struct Base
{
    virtual void vf1(){print();};
    virtual void vf2(){print();};
    virtual void vf3(){print();};
    virtual B* vf4(){print();};
    virtual B* vf5(){print();};
};
 
class D : private B
{
    friend struct Derived; // in Derived, B is an accessible base of D
};
 
class A; // forward-declared class is an incomplete type
 
struct Derived : public Base
{
    void vf1(){print();};    // virtual, overrides Base::vf1()
    void vf2(int){print();}; // non-virtual, hides Base::vf2()

    D* vf4(){print();};      // overrides Base::vf4() and has covariant return type
//  A* vf5(){print();};      // Error: A is incomplete type
};
 
int main()
{
    Derived d;
    Base& br = d;
    Derived& dr = d;
 
    std::cout<<typeid(br.vf4()).name()<<std::endl; // calls Derived::vf4() and converts the result to B*
    std::cout<<typeid(dr.vf4()).name()<<std::endl; // calls Derived::vf4() and does not convert the result to B*

    B* p = br.vf4(); // calls Derived::vf4() and converts the result to B*
    D* q = dr.vf4(); // calls Derived::vf4() and does not convert the result to B*
}

这是输出:

P1B
P1D
virtual D* Derived::vf4()
virtual D* Derived::vf4()
贾米特

被调用的重写函数的返回类型

注意单词选择。调用的函数,而不是被执行的函数。您的示例专注于执行相同的功能。被调用的函数取决于你如何调用(编译时),而不是如何应答调用(运行时)。

ref对于type的引用A&,表达式ref.foo()是 call to A::foo()调用完成后,多态性可能会启动并将执行重定向到不同的函数,但这不会改变调用的内容。你打了电话A::foo(),但也许是B::foo()那个人接了电话。虚函数就是这样棘手的,相互覆盖。

你介意吗?并不真地。您对结果感兴趣,而不是对谁提供结果感兴趣。只要接听电话的功能遵守由 签订的合同A::foo(),一切都很好。如果他们愿意,他们可以换班。

在这个故事中,合约包含返回值的类型。这不能被弄乱,否则调用堆栈会被破坏。不幸的是,可能存在协变返回类型。幸运的是,B::foo()知道如果它覆盖 for A::foo(),它必须适应当前的合约并在返回时免费提供隐式转换。不言而喻。

尽管如此,B仍将转换视为降级。痞子使用A参考文献很好。让他们有自己劣等的回报价值;好东西是为那些坚持B引用的少数歧视者保留的。这些优秀的人会打电话B::foo()给他们,他们会跳过降级/转换。优雅。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

std :: bind的返回类型隐式转换为两个不同的显式构造函数

返回值的隐式类型转换

隐式类型转换的调用函数

覆盖打字稿中的函数返回类型

返回与泛型定义的类型不同的类型的错误:“无法将类型List <A>隐式转换为List <tableType>”

错误无法在返回时将类型'string'隐式转换为'System.DateTime'

无法将类型“ void”隐式转换为“ System.Collections.Generic.List”以用于返回语句

std :: function是否允许从引用隐式转换为返回类型的副本?

从接口覆盖通用返回类型

C#-隐式转换或推断通用返回类型

函数隐式具有返回类型“ any”错误

在 TypeScript 中将函数类型转换为这些函数的返回类型

自动覆盖 TypeScript 子类中多个函数的返回类型

是否可以覆盖全局函数的phpdoc返回类型?

C++ 覆盖 void 函数返回类型导致构建失败

如何将类型投影转换为隐式的PDT?

如何隐式地从`any`转换为更强的类型

然后如何包含调用和返回而不能隐式转换

如何在成员函数中使用隐式类型转换?

隐式转换为数组索引类型

无法将类型 *** 隐式转换为 ****

如何返回与调用函数相同的类型?

C# 返回错误“无法将类型‘int’隐式转换为‘string’”,即使没有给出 int

C ++构造函数隐式类型转换

覆盖和返回类型兼容性

Java未检查的覆盖返回类型

具有通用返回类型的覆盖方法

JSDoc覆盖继承类方法的返回类型

覆盖属性返回类型,C#