返回类型与智能指针的协方差 [英] Return Type Covariance with Smart Pointers
问题描述
在C ++中,我们可以这样做:
struct Base
{
virtual Base * Clone )const {...}
virtual〜Base(){}
};
struct Derived:Base
{
virtual Derived * Clone()const {...} //覆盖Base :: Clone
};然而,以下不会做同样的伎俩:
< b $ b struct Base
{
virtual shared_ptr< Base> Clone()const {...}
virtual〜Base(){}
};
struct Derived:Base
{
virtual shared_ptr< Derived> Clone()const {...} //隐藏Base :: Clone
};
在此示例中 Derived :: Clone
隐藏 Base :: Clone
,而不是覆盖重写成员的类型可以仅从引用(或指针)改变到引用(或指针)到引用。有什么聪明的解决方法吗?当然可以认为 Clone
函数应该返回一个简单的指针,但让我们现在忘记它 - 这只是一个说明性的例子。我正在寻找一种方法,使虚拟函数的返回类型从智能指针 Base
改为智能指针 Derived
。
提前感谢!
我的第二个例子确实不编译,感谢 Iammilind 解决方案你不能直接做,但有几种方法来模拟它, - 虚拟接口习惯。
对原始指针使用协方差,然后将它们包装
struct Base
{
private:
virtual Base * doClone()const {...}
public:
shared_ptr< Base> ; Clone()const {return shared_ptr< Base>(doClone()); }
virtual〜Base(){}
};
struct Derived:Base
{
private:
virtual Derived * doClone()const {...}
public:
shared_ptr< Derived> Clone()const {return shared_ptr< Derived>(doClone()); }
};
这只适用于你实际上有一个原始指针。
通过转换来模拟协方差
struct Base
{
private:
virtual shared_ptr< base> doClone()const {...}
public:
shared_ptr< Base> Clone()const {return doClone(); }
virtual〜Base(){}
};
struct Derived:Base
{
private:
virtual shared_ptr< Base> doClone()const {...}
public:
shared_ptr< Derived> Clone()const
{return static_pointer_cast< Derived>(doClone()); }
};
这里必须确保所有覆盖 Derived :: doClone 实际上返回指向 Derived
或从其派生的类的指针。
In C++ we can do this:
struct Base
{
virtual Base* Clone() const { ... }
virtual ~Base(){}
};
struct Derived : Base
{
virtual Derived* Clone() const {...} //overrides Base::Clone
};
However, the following won't do the same trick:
struct Base
{
virtual shared_ptr<Base> Clone() const { ... }
virtual ~Base(){}
};
struct Derived : Base
{
virtual shared_ptr<Derived> Clone() const {...} //hides Base::Clone
};
In this example Derived::Clone
hides Base::Clone
rather than overrides it, because the standard says that the return type of an overriding member may change only from reference(or pointer) to base to reference (or pointer) to derived. Is there any clever workaround for this? Of course one could argue that the Clone
function should return a plain pointer anyway, but let's forget it for now - this is just an illustratory example. I am looking for a way to enable changing the return type of a virtual function from a smart pointer to Base
to a smart pointer to Derived
.
Thanks in advance!
Update: My second example indeed doesn't compile, thanks to Iammilind
解决方案 You can't do it directly, but there are a couple of ways to simulate it, with the help of the Non-Virtual Interface idiom.
Use covariance on raw pointers, and then wrap them
struct Base
{
private:
virtual Base* doClone() const { ... }
public:
shared_ptr<Base> Clone() const { return shared_ptr<Base>(doClone()); }
virtual ~Base(){}
};
struct Derived : Base
{
private:
virtual Derived* doClone() const { ... }
public:
shared_ptr<Derived> Clone() const { return shared_ptr<Derived>(doClone()); }
};
This only works if you actually have a raw pointer to start off with.
Simulate covariance by casting
struct Base
{
private:
virtual shared_ptr<Base> doClone() const { ... }
public:
shared_ptr<Base> Clone() const { return doClone(); }
virtual ~Base(){}
};
struct Derived : Base
{
private:
virtual shared_ptr<Base> doClone() const { ... }
public:
shared_ptr<Derived> Clone() const
{ return static_pointer_cast<Derived>(doClone()); }
};
Here you must make sure that all overrides of Derived::doClone
do actually return pointers to Derived
or a class derived from it.
这篇关于返回类型与智能指针的协方差的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!