代码之家  ›  专栏  ›  技术社区  ›  Gaurav Sehgal

用不同的返回类型重写虚函数

  •  1
  • Gaurav Sehgal  · 技术社区  · 6 年前

    我知道,如果返回类型是协变的,则可以使用返回类型重写虚拟函数。

    但是我们可以使用更改后的返回类型吗?或者,返回类型将隐式转换为基类函数的返回类型,如 B* A* 在这里。

    class A
    {
        public:
        virtual A *func()
        {
            A *obj=0;
            return obj;
        }
    };
    
    class B:public A
    {
        public:
        virtual B *func()
        {
           B *obj =0;
           return obj;
        }
    };
    
    int main()
    {
        A *obj = new B();
        obj->func();              // does in fact call B::func()
        B *obj2 = obj->func();    // throws error: invalid conversion from 'A*' to 'B*'
    
        return 0;
    }
    

    看起来 obj->func() 正在返回 一个* 而不是 乙* 因此我得到了这个转换错误。

    3 回复  |  直到 6 年前
        1
  •  3
  •   StoryTeller - Unslander Monica    6 年前

    静态类型检查必须仍然保持,即使动态类型在实现中做了一些稍微不同的事情。所以它实际上取决于被指向的对象的静态类型。当您调用 A* ,返回类型指定为 A* 是的。

    如果你把它叫做 B* ,函数的返回类型应该是(静态的)a 乙* 是的。

    B *obj = new B();
    obj->func();              
    B *obj2 = obj->func();   // Okay now
    

    每当你在C++中处理运行时多语言,它就是 静态类型 确定接口的对象。

        2
  •  3
  •   Jarod42    6 年前

    静态类型 obj A* 所以 obj->func() 会用到 A *A::func() 宣言:

    • 返回类型( 一个* )
    • 访问说明符( public: )
    • 默认参数(不适用)

    动态类型为 B* ,所以它将调用 B* B::func() 由于协变类型实际上会在 一个* 是的。

        3
  •  0
  •   lubgr    6 年前

    在您的示例中,继承层次结构中的类型可以隐式降级 B A ,这也允许协变返回类型。但你试着含蓄地向上投射,

    B *obj2 = obj->func();
    

    不能工作是因为 obj 是一个 一个 实例,以及 func() 静态绑定到 一个 提供。如果有必要 B* A::func() 你可以用一个明确的演员阵容

    auto *obj2 = dynamic_cast<B*>(obj->func());
    

    但这是一种不好的模式,因为它损害了多态性的全部要点。