C++ 模拟协变返回类型行为

C++ 模拟协变返回类型行为,c++,C++,我想以一种方式编写Deriveds foo,当它被调用为派生对象时,它将返回后代。我知道,使用协变返回类型可以很容易地做到这一点。但是如果我不能使用这个功能呢。如何在上面的代码中模拟此功能 class Ancestor{}; class Descendant : public Ancestor{}; class Base { public: Ancestor foo(void); }; class Derived : public Base { public: // Do not r

我想以一种方式编写Deriveds foo,当它被调用为派生对象时,它将返回后代。我知道,使用协变返回类型可以很容易地做到这一点。但是如果我不能使用这个功能呢。如何在上面的代码中模拟此功能

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);
};
如果您可以使用指针,那么只需返回一个上置的Decentant指针。返回的指针将指向子体,并且假设方法是虚拟的,其行为也将类似于子体

我想以一种方式编写DerivedsFoo,当它被调用为派生对象时,它将返回后代

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

C++支持协变原始指针和原始引用结果。对于智能指针结果类型,如
boost::shared_ptr
std::auto_ptr
必须通过在派生类中重新定义公共函数来实现协方差。这与您的问题类似,因为协变函数按值返回–不是原始指针或原始引用–但它也不同于您的问题,因为智能指针类型之间没有继承关系,而是上转换

下面是一个例子:

// Do not redefine foo as : Descendant foo(void);
#包括
#包括
使用名称空间std;
结构祖先{virtual~祖先(){};
结构后代:祖先{};
阶级基础
{
受保护的:
虚拟祖先*virtualFoo()常量
{
返回新祖先();
}
公众:
auto_ptr foo()常量
{
返回auto_ptr(virtualFoo());
}
};
派生类:公共基
{
受保护的:
虚拟后代*virtualFoo()常量
{
返回新的子体();
}
公众:
auto_ptr foo()常量
{
返回auto_ptr(virtualFoo());
}
};
#包括
int main()
{
基本对象;
派生派生对象;
Base&baseRef=derivedObject;

cout As
Base::foo
按值返回一个
祖先
Derived::foo
无论如何都不能有协变返回。运行时多态性通过指针或引用和虚拟调度工作。如果不知道真正的问题,就很难知道什么对你有用…例如,你能返回一个reference吗是的,我可以。我的问题类似于“如何在不支持协变返回类型的编译器(如旧编译器)中解决此问题”是的-这里的关键点是,协变返回类型是作为此简单多态机制的显式文档添加的(允许进行更多的编译器检查、API中提供更多信息的返回类型、可能的额外优化)-但多态性在引入协变返回类型之前工作得很好,并保持向后兼容性。
// Do not redefine foo as : Descendant foo(void);
#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;
}