gpt4 book ai didi

c++ - 函数参数的继承

转载 作者:搜寻专家 更新时间:2023-10-31 02:09:25 25 4
gpt4 key购买 nike

我想知道如何使用派生函数参数正确覆盖派生类的函数?
例如

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);
};

最佳答案

您可以用派生类/基类代替返回值/参数的想法被称为协变返回类型和逆变参数。

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

C++ 不支持参数的逆变,即用派生的 Base* 参数替换基接口(interface)中的 Derived* 参数,但您可以模拟它具有重载和覆盖。

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*。基本接口(interface)要求它是 DerivedValue*

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

派生接口(interface)比基接口(interface)更宽松,并且它提供的保证至少与原始接口(interface)一样好,或者更好


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

其次,你的逻辑有问题。使用 Liskov substitution principle ,您的 B 必须能够替代 A

但是你的 Bf 的参数上比 A 有一个更受限制的契约。 A 需要一个 X 参数,B 需要它不仅是一个 X 而且是一个 Y 还有。

struct X1{};
struct X2{};
struct Y:X1,X2{};

struct A {
virtual void foo( Y* ) = 0;
virtual ~A() {}
}
struct B1:A {
virtual void foo( Y* ptr ) final override { foo( static_cast<X1*>(ptr) ); }
virtual void foo( X1* ) = 0;
}
struct B2:A {
virtual void foo( Y* ptr ) final override { foo( static_cast<X2*>(ptr) ); }
virtual void foo( X2* ) = 0;
}

这对应于您的示例。派生接口(interface)更允许其(隐式输入)参数。

您可以跳过各种步骤以获得支持协方差的仅输出参数,或者简单地返回它们。

关于c++ - 函数参数的继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46589823/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com