目前我正面临以下问题。我需要一个派生类中的成员函数,它可以处理不同的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但我尽量避免这种情况)。
所以现在我没有想法如何解决问题,但也许你有一个可以帮助我。
提前感谢您的回答。
答案 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()