![](/img/trans.png)
[英]Can I use C++11 smart pointers as a message return type in the C++ Actor Framework?
[英]Return Type Covariance with Smart Pointers
在C ++中,我們可以這樣做:
struct Base
{
virtual Base* Clone() const { ... }
virtual ~Base(){}
};
struct Derived : Base
{
virtual Derived* Clone() const {...} //overrides Base::Clone
};
但是,以下方法不會起到相同的作用:
struct Base
{
virtual shared_ptr<Base> Clone() const { ... }
virtual ~Base(){}
};
struct Derived : Base
{
virtual shared_ptr<Derived> Clone() const {...} //hides 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
或從其Derived
的類的指針。
@ymett使用CRTP技術改善了一個很好的答案 。 這樣,您不必擔心忘記在派生對象中添加非虛擬函數。
struct Base
{
private:
virtual Base* doClone() const { ... }
public:
shared_ptr<Base> Clone() const { return shared_ptr<Base>(doClone()); }
virtual ~Base(){}
};
template<class T>
struct CRTP_Base : Base
{
public:
shared_ptr<T> Clone() const { return shared_ptr<T>(doClone()); }
};
struct Derived : public CRTP_Base<Derived>
{
private:
virtual Derived* doClone() const { ... }
};
我想到了一些主意。 首先,如果可以使用第一個版本,則只需保留該Clone
即可, 然后編寫另一個受保護的_clone
,該_clone
實際上返回派生的指針。 兩個Clone
都可以使用它。
這就引出了一個問題,為什么要這樣呢? 另一種方法是強制(外部)函數,在該函數中,您會收到一個shared_ptr<Base>
並且可以將其強制到shared_ptr<Derived>
。 也許是這樣的:
template <typename B, typename D>
shared_ptr<D> coerce(shared_ptr<B>& sb) throw (cannot_coerce)
{
// ...
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.