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