C ++ 11传递shared_pointer与std :: any

时间:2018-02-03 20:35:37

标签: c++11 templates pointers boost any

目前我正面临以下问题。我需要一个派生类中的成员函数,它可以处理不同的shared_ptr类型并使用它来执行自定义的东西。基类应确保实现此类成员函数,但仅在其他开发人员创建新派生类时才知道特定的shared_ptr类型。因此,由于c ++不支持虚拟模板函数,模板不是解决方案。

shared_ptrs包含protobuf消息特定的发布者或订阅者。这里有一段代码:

std::shared_ptr<Publisher<ProtobufMessageType1>> type1 = std::make_shared<ProtobufMessageType1>();
std::shared_ptr<Publisher<ProtobufMessageType2>> type2 = std::make_shared<ProtobufMessageType2>();

class derived : base
{

  void takeThePointerAndDoSpecificStuff( std::shared_ptr<PubOrSub<SpecificProtobufMessage>>) override
  {
     // check type and bind specific callback
  }
}

一种解决方案可能是将shared_ptr转换为基类,但由于protobuf消息基类是纯虚拟的,因此无法实现。另一种解决方案是转换原始指针并仅传输此指针,但我也需要方法中的share_ptr引用计数(由于绑定)。

所以我进一步寻找解决方案和std :: any可能是一个但问题是c ++ 11没有std :: any(肯定可以使用boost但我尽量避免这种情况)。

所以现在我没有想法如何解决问题,但也许你有一个可以帮助我。

提前感谢您的回答。

1 个答案:

答案 0 :(得分:2)

  

一个解决方案可能是将shared_ptr强制转换为基类,但由于protobuf消息基类是纯虚拟的,所以不可能

这根本不是真的。您可以使用抽象基础的共享指针:

<强> Live On Coliru

#include <memory>
#include <iostream>

struct Base {
    virtual ~Base() = default;
    virtual void foo() const = 0;
};

struct D1 : Base { virtual void foo() const override { std::cout << __PRETTY_FUNCTION__ << "\n"; } };
struct D2 : Base { virtual void foo() const override { std::cout << __PRETTY_FUNCTION__ << "\n"; } };

int main() {
    std::shared_ptr<Base> b = std::make_shared<D1>();
    std::shared_ptr<Base> c = std::make_shared<D2>();

    b->foo();
    c->foo();
}

打印

virtual void D1::foo() const
virtual void D2::foo() const

更多想法

即使您没有拥有共同基础(或根本没有基础),您仍然可以使用shared_pointer。一个特别有用的习惯是使用shared_pointer<void>

<强> Live On Coliru

#include <memory>
#include <iostream>

struct D1 { 
    void foo() const { std::cout << __PRETTY_FUNCTION__ << "\n"; } 
    ~D1()            { std::cout << __PRETTY_FUNCTION__ << "\n"; }
};
struct D2 {
    void bar() const { std::cout << __PRETTY_FUNCTION__ << "\n"; }
    ~D2()            { std::cout << __PRETTY_FUNCTION__ << "\n"; }
};

int main() {
    std::shared_ptr<void> b = std::make_shared<D1>();
    std::shared_ptr<void> c = std::make_shared<D2>();

    std::static_pointer_cast<D1>(b)->foo();
    std::static_pointer_cast<D2>(c)->bar();
}

打印

void D1::foo() const
void D2::bar() const
D2::~D2()
D1::~D1()

请参阅:http://www.boost.org/doc/libs/1_66_0/libs/smart_ptr/doc/html/smart_ptr.html#techniques_using_shared_ptr_void_to_hold_an_arbitrary_object