如何在shared_ptr的子类之间进行转换?

时间:2015-05-25 07:12:01

标签: c++ c++11 shared-ptr

我是std::shared_ptr的子类,我正在尝试在子类上编写cast()方法,因此我可以隐藏static_pointer_cast,但我无法将代码转到编译。我错过了什么?

演示:http://ideone.com/nbPHbs

template<class T>
class Handle : public std::shared_ptr<T> {
public:
    template<class ResultType>
    inline Handle<ResultType>
    cast() {
        // Cast Handle to shared_ptr
        auto T_sp = static_cast< std::shared_ptr<T> >(*this);
        // Cast the data
        auto ResultType_sp = std::static_pointer_cast<ResultType>(T_sp);
        // Cast back to Handle
        return static_cast< Handle<ResultType> >(ResultType_sp);
    }
};


// Usage
struct Base {};
struct Child : public Base {};
auto child_ptr = Handle<Child>(new Child());
auto base_ptr  = child_ptr.cast<Base>(); // Error with this

这是我收到的错误消息:

error: no matching function for call to 'Handle<Child>::Handle(Child*)'
auto child_ptr = Handle<Child>(new Child());
                                         ^

**编辑 我在这里使用继承是因为它是原始template<T> using std::shared_ptr<T> Handle<T>;的一次写入/丢弃代码所以,继承是需要最少量代码更改的自然进程。因为看起来这段代码看起来会更长一些,所以在发布这个问题之前我确实切换到了构图,我只是想知道为什么它没有编译;我在几年内没有完成任何c ++,所以我的技能有点生疏。

3 个答案:

答案 0 :(得分:0)

我没有看到在这里继承shared_ptr的任何好处,它不值得麻烦imho。如果您认为std :: static_pointer_cast很大且很难看,您可以通过内联函数解决这个问题

template <typename TOUT, typename TIN>
inline std::shared_ptr<TOUT> cast(TIN in)
{
    return std::static_pointer_cast<TOUT>(in);
}

// Usage
struct Base {};
struct Child : public Base {};

int main() {
    std::shared_ptr<Child> child_ptr = std::make_shared<Child>();
    std::shared_ptr<Base> base_ptr  = cast<Base>(child_ptr); // Error with this
    return 0;
}

答案 1 :(得分:0)

这个答案正在讨论是否继承std :: shared_ptr是一个好主意。我会建议在继续讨论之前阅读这些讨论。

现在就出现问题:

如果你真的想继续这条路线,那么你所缺少的是构造函数。 编译器只为您创建默认构造函数。 由于错误消息显示您需要Handle<Child>::Handle(Child*)

获取所需构造函数的最简单方法是重用基类中的构造函数:

template<class T>
class Handle : public std::shared_ptr<T> {
public:
    using std::shared_ptr<T>::shared_ptr;
...

答案 2 :(得分:-1)

您的类没有任何构造函数,因此,当您尝试编译时,如果您尝试使用带参数的构造函数,它将会失败。

如果你想继承shared_ptr(我不鼓励,因为基础析构函数不是虚拟的,你的程序很可能会大量泄漏内存)你应该在你的班级中添加这一行体:

using std::shared_ptr<T>::shared_ptr;