我想知道如何使用派生函数参数正确覆盖派生类的功能?
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);
};
答案 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
是参数类型的逆变的一个例子。 ptr
,contra_example
的参数,DerivedInterface
的参数可以是任意Value*
。基本接口要求它是DerivedValue*
。
我们可以覆盖基础contra_example
,然后转发到我们内部的“更多接受”实现,即DerivedInterface
中的重载。
派生接口比基本接口更宽松,它提供的保证至少与原始接口一样好或更好。
现在让我们回到你的问题。首先,不,编译器不会为你做这件事。
其次,你的逻辑是有缺陷的。使用Liskov substitution principle,您的B
必须能够接受A
。
但是,B
的{{1}}参数与f
的约束受限制。 A
需要A
参数,X
要求它不仅是B
,还需要X
。
Y
这对应于你的例子。派生接口更容易接受它们(隐式输入)的参数。
你可以通过箍来获得支持协方差的out-only参数,或者只是返回它们。