class Ancestor{};
class Descendant : public Ancestor{};
class Base
{
public:
Ancestor foo(void);
};
class Derived : public Base
{
public:
// Do not redefine foo as : Descendant foo(void);
};
我想以一种方式编写Deriveds foo,当它被调用为Derived对象时,它将返回Descendant。我知道这可以通过协变返回类型使用轻松完成。但是如果我不能使用这个功能呢?我如何在上面的代码中模拟此功能?
答案 0 :(得分:3)
我想以一种方式编写Deriveds foo,当它被调用为Derived对象时,它将返回Descendant。
// Do not redefine foo as : Descendant foo(void);
由于foo
按值返回Ancestor
,因此实现(有限种类)协方差的唯一方法是重新定义foo
。因此,要求是矛盾的。
C ++支持协变原始指针和原始引用结果。使用智能指针结果类型,例如boost::shared_ptr
或std::auto_ptr
,必须通过重新定义派生类中的公共函数来实现协方差。这与您的问题类似,因为协变函数按值返回 - 不是原始指针或原始引用 - 但它也与您的问题不同,因为智能指针类型之间没有继承关系,而是上转换。 / p>
以下是一个例子:
#include <memory>
#include <typeinfo>
using namespace std;
struct Ancestor{ virtual ~Ancestor(){} };
struct Descendant : Ancestor {};
class Base
{
protected:
virtual Ancestor* virtualFoo() const
{
return new Ancestor();
}
public:
auto_ptr<Ancestor> foo() const
{
return auto_ptr<Ancestor>( virtualFoo() );
}
};
class Derived : public Base
{
protected:
virtual Descendant* virtualFoo() const
{
return new Descendant();
}
public:
auto_ptr<Descendant> foo() const
{
return auto_ptr<Descendant>( virtualFoo() );
}
};
#include <iostream>
int main()
{
Base baseObject;
Derived derivedObject;
Base& baseRef = derivedObject;
cout << typeid( *baseObject.foo() ).name() << endl;
cout << typeid( *derivedObject.foo() ).name() << endl;
cout << typeid( *baseRef.foo() ).name() << endl;
}
在前两个foo
调用中,静态结果类型对应于动态类型,这是协方差从使用代码的角度来看的全部内容。
在上一次foo
调用中,foo
结果的静态类型为std::auto_ptr<Ancestor>
,而指针对象的类型为Descendant
。
请注意,覆盖虚函数依赖于C ++对原始指针类型的协变结果的内置支持。
干杯&amp;第h。,
答案 1 :(得分:2)
Ancestor * Derived::foo
{
// Do whatever
return new Descendant ( );
}
如果你可以使用指针,那么只需返回一个上升的Decendant指针。返回的指针将指向一个后代,并且假设方法是虚拟的,它也像一个后代一样。