C++ 如何在返回共享ptr时实现协变返回类型? 使用名称空间boost; A类{}; B类:公共A{}; X类{ 虚拟共享_ptr foo(); }; Y类:公共X类{ 虚拟共享_ptr foo(); };

C++ 如何在返回共享ptr时实现协变返回类型? 使用名称空间boost; A类{}; B类:公共A{}; X类{ 虚拟共享_ptr foo(); }; Y类:公共X类{ 虚拟共享_ptr foo(); };,c++,boost,return-value,covariance,shared-ptr,C++,Boost,Return Value,Covariance,Shared Ptr,返回类型不是协变的(因此,它们也不是合法的),但如果我使用原始指针,它们就会是协变的。如果有的话,人们普遍接受的解决方法是什么?我认为根本不可能找到解决方案,因为协方差依赖于指针算法,而指针算法与智能指针不兼容 当Y::foo向动态调用者返回shared_ptr时,必须在使用前将其强制转换为shared_ptr。在你的例子中,一个 B*可以简单地被重新解释为 A*,但是对于多重继承,你需要一些魔术来告诉C++关于 StasyType(SyddyPt::GET())< /> > < P>不直接,

返回类型不是协变的(因此,它们也不是合法的),但如果我使用原始指针,它们就会是协变的。如果有的话,人们普遍接受的解决方法是什么?

我认为根本不可能找到解决方案,因为协方差依赖于指针算法,而指针算法与智能指针不兼容


Y::foo
向动态调用者返回
shared_ptr
时,必须在使用前将其强制转换为
shared_ptr
。在你的例子中,一个<代码> B*<代码>可以简单地被重新解释为<代码> A*<代码>,但是对于多重继承,你需要一些魔术来告诉C++关于<代码> StasyType(SyddyPt::GET())< /> >

< P>不直接,但是您可以通过使实际的虚拟函数从类外部无法访问并将虚拟函数调用包装到非虚拟函数中来伪造它。缺点是您必须记住在每个派生类上实现这个包装器函数。但是您可以通过将virtul函数声明和包装器放入宏中来解决这个问题

using namespace boost;

class A {};
class B : public A {};

class X {
  virtual shared_ptr<A> foo();
};

class Y : public X {
  virtual shared_ptr<B> foo();
};
使用名称空间boost;//对于共享\u ptr,进行\u共享和静态\u指针\u强制转换。
//克隆()函数的“假”实现。
#定义克隆(MyType)\
共享的\u ptr克隆()\
{ \
shared_ptr res=clone_impl()\
断言(dynamic_cast(res.get())!=0)\
返回静态\u指针\u转换(res)\
}
阶级基础
{
受保护的:
//clone()函数的实际实现。
虚拟共享_ptrclone_impl(){return make_shared(*this);}
公众:
//非虚拟共享_ptr clone();
克隆(基)
};
派生类:公共基
{
受保护的:
虚拟共享_ptrclone_impl(){return make_shared(*this);}
公众:
//非虚拟共享_ptr clone();
克隆(派生)
};
int main()
{
shared_ptr p=使_共享();
共享_ptr clone=p->clone();
返回0;
}

我只是返回一个空指针,并立即将其包装在共享指针中。

Hmm的可能重复,“基本上”协方差取决于转换,也许应该使用隐式转换类型。但这仍然不适用于
shared\u ptr
“但这仍然不适用于
shared\u ptr
”我不明白:shared\u ptr不可转换吗?@curiousguy哦,是的。不过,这仍然只是一个假设。这个问题已经有一段时间没有得到回答了。现在c++11已经过时了,还有更好的方法吗?@CoryBeutler。不,如果您想使用共享\u ptr。如果您愿意放弃shared_ptr并愿意使用侵入式引用计数,那么是的。在这种情况下,函数将返回原始指针并获得自动重新计数,您只需将结果分配给智能指针(例如boost::intrusive_ptr)。您几乎不想将其他人的裸指针包装到共享_ptr。
using namespace boost; // for shared_ptr, make_shared and static_pointer_cast.

// "Fake" implementation of the clone() function.
#define CLONE(MyType) \
    shared_ptr<MyType> clone() \
    { \
        shared_ptr<Base> res = clone_impl(); \
        assert(dynamic_cast<MyType*>(res.get()) != 0); \
        return static_pointer_cast<MyType>(res); \
    }

class Base 
{
protected:
    // The actual implementation of the clone() function. 
    virtual shared_ptr<Base> clone_impl() { return make_shared<Base>(*this); }

public:
    // non-virtual shared_ptr<Base> clone();
    CLONE(Base)
};

class Derived : public Base
{
protected:
    virtual shared_ptr<Base> clone_impl() { return make_shared<Derived>(*this); }

public:
    // non-virtual shared_ptr<Derived> clone();
    CLONE(Derived)
};


int main()
{
    shared_ptr<Derived> p = make_shared<Derived>();
    shared_ptr<Derived> clone = p->clone();

    return 0;
}