模拟协变返回类型行为

时间:2011-01-17 04:36:31

标签: c++

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。我知道这可以通过协变返回类型使用轻松完成。但是如果我不能使用这个功能呢?我如何在上面的代码中模拟此功能?

2 个答案:

答案 0 :(得分:3)

  

我想以一种方式编写Deriveds foo,当它被调用为Derived对象时,它将返回Descendant。

// Do not redefine foo as : Descendant foo(void);

由于foo按值返回Ancestor,因此实现(有限种类)协方差的唯一方法是重新定义foo。因此,要求是矛盾的

C ++支持协变原始指针和原始引用结果。使用智能指针结果类型,例如boost::shared_ptrstd::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指针。返回的指针将指向一个后代,并且假设方法是虚拟的,它也像一个后代一样。