函数参数的继承

时间:2017-10-05 15:46:06

标签: c++ inheritance override

我想知道如何使用派生函数参数正确覆盖派生类的功能?
e.g。

struct X;
struct Y:X
struct Z:X

class A {
    public:
      int f(int, X);    
};

class B : A{
    public:
       int f(int, Y);
};

class C : A{
    public:
       int f(int, Z);
};

1 个答案:

答案 0 :(得分:2)

您可以为返回值/参数提供子类派生/基类的想法称为协变返回类型和逆变参数。

在C ++中,virtual指针的引用和指针返回类型在派生类型中具有协变重载;您可以在派生类型中向基本返回类型返回更受限制的(指针或引用)。

在C ++中不支持将基本接口中的Derived*参数替换为派生中的Base*参数的参数的反演,但您可以使用重载和覆盖来模拟它。 / p>

struct BaseValue {};
struct DerivedValue:BaseValue {};
struct MoreDerivedValue:DerivedValue {};

struct BaseInterface {
  virtual void contra_example( DerivedValue* ptr ) = 0;
  virtual DerivedValue* co_example() = 0;
  virtual ~BaseInterface() {}
};

struct DerivedInterface:BaseInterface {
  virtual void contra_example( DerivedValue* ptr ) override final {
    contra_example( static_cast<Value*>( ptr ) );
  }
  void contra_example( Value* ptr ) override = 0;

  virtual MoreDerivedValue* co_example() override = 0;
};

co_example是返回类型中协方差的一个示例。编译器会根据指针和对类型层次结构的引用进行协方差处理时,编译器会自动执行此操作。

contra_example是参数类型的逆变的一个例子。 ptrcontra_example的参数,DerivedInterface的参数可以是任意Value*。基本接口要求它是DerivedValue*

我们可以覆盖基础contra_example,然后转发到我们内部的“更多接受”实现,即DerivedInterface中的重载

派生接口比基本接口更宽松,它提供的保证至少与原始接口一样好或更好

现在让我们回到你的问题。首先,不,编译器不会为你做这件事。

其次,你的逻辑是有缺陷的。使用Liskov substitution principle,您的B必须能够接受A

但是,B的{​​{1}}参数与f的约束受限制A需要A参数,X要求它不仅是B,还需要X

Y

这对应于你的例子。派生接口更容易接受它们(隐式输入)的参数。

你可以通过箍来获得支持协方差的out-only参数,或者只是返回它们。