C++ 11 传递 shared_pointer 就像 std::any

C++ 11 passing shared_pointer like with std::any

目前我面临以下问题。我需要派生的 class 中的成员函数,它可以处理不同的 shared_ptr 类型并用它做自定义的事情。基础 class 应该确保实现这样的成员函数,但是特定的 shared_ptr 类型只有在其他开发人员创建新的派生 class 时才知道。因此,由于 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 转换为基础 class 但这是不可能的,因为 protobuf 消息基础 class 是纯虚拟的。另一种解决方案是转换原始指针并只传输这个,但我还需要方法中的 share_ptr 引用计数(由于绑定)。

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

所以现在我不知道如何解决这个问题,但也许你有一个可以帮助我。

提前感谢您的回答。

One solution could be casting shared_ptr to base class but it is not possible because the protobuf message base class is pure virtual

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

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