本文介绍了动态指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我想将基类指针转换为派生类指针作为函数参数,而不使用dynamic_pointer_cast
I'd like to convert a base class pointer to a derived class pointer as a function argument without using dynamic_pointer_cast
class Base { public: typedef std::shared_ptr < Base > Ptr; virtual ~Base ( ); ... }; class Derive : public Base { public: typedef std::shared_ptr < Derive > Ptr; ... }; void foo( Derive::Ptr ptr ) { ... } Base::Ptr ptr1 ( new Derive ); foo( ptr1 );上面的代码在调用foo时会报错。这可以通过使用std :: dynamic_pointer_cast将ptr1类型转换为Dervie指针来避免。
The above code will give an error while calling foo. This can be avoided by typecasting ptr1 into a Dervie pointer using std::dynamic_pointer_cast.
Base::Ptr ptr1 ( new Derive ); foo ( std::dynamic_pointer_cast < Derive > ( ptr1 ) );我想创建一个回调函数的映射,它将自动类型化基类指针并调用相应的
I want to create a map of callback functions that will automatically typecast a base class pointer and call the corresponding function based on the type of derived class.
推荐答案这适用于我。
#include <iostream> #include <set> #include <memory> class Base { public: typedef std::shared_ptr < Base > Ptr; virtual ~Base () {} }; // Dispatch mechanism to dispatch derived class specific // functions for foo. // Base class. struct FooDispatcher { static int registerDispatcher(FooDispatcher* dispatcher) { dispatcherSet.insert(dispatcher);; return 0; } static void dispatch(Base::Ptr ptr) { std::set<FooDispatcher*>::iterator iter = dispatcherSet.begin(); std::set<FooDispatcher*>::iterator end = dispatcherSet.end(); for ( ; iter != end; ++ iter ) { if ( (*iter)->canProcess(ptr) ) { (*iter)->process(ptr); return; } } } virtual bool canProcess(Base::Ptr ptr) = 0; virtual void process(Base::Ptr ptr) = 0; static std::set<FooDispatcher*> dispatcherSet; }; std::set<FooDispatcher*> FooDispatcher::dispatcherSet; void foo( Base::Ptr ptr ) { FooDispatcher::dispatch(ptr); } // A class template for derived classes to use when they // have an implementation of foo. template <typename T> struct FooDerivedDispatcher : public FooDispatcher { virtual bool canProcess(Base::Ptr ptr) { return (std::dynamic_pointer_cast<T>(ptr) != nullptr); } virtual void process(Base::Ptr ptr) { fooImpl(std::dynamic_pointer_cast<T>(ptr)); } }; // Derived1 and its implementation of foo. class Derived1 : public Base { public: typedef std::shared_ptr < Derived1 > Ptr; }; void fooImpl( Derived1::Ptr ptr ) { std::cout << "Came to fooImpl(Derived1::Ptr).\n"; } // Register the FooDispatcher for Derived1 int dummy1 = FooDispatcher::registerDispatcher(new FooDerivedDispatcher<Derived1>()); // Derived2 and its implementation of foo. class Derived2 : public Base { public: typedef std::shared_ptr < Derived2 > Ptr; }; void fooImpl( Derived2::Ptr ptr ) { std::cout << "Came to fooImpl(Derived2::Ptr).\n"; } // Register the FooDispatcher for Derived1 int dummy2 = FooDispatcher::registerDispatcher(new FooDerivedDispatcher<Derived2>()); // Test... int main() { Base::Ptr ptr(new Derived1); foo(ptr); ptr = Base::Ptr(new Derived2); foo(ptr); }输出:
Came to fooImpl(Derived1::Ptr). Came to fooImpl(Derived2::Ptr).更新
更简单的调度机制。感谢@MooingDuck。
A simpler dispatch mechanism... Thanks to @MooingDuck.
#include <iostream> #include <vector> #include <memory> class Base { public: typedef std::shared_ptr < Base > Ptr; virtual ~Base () {} }; struct FooDispatcher { template<class Derived, class Func> bool registerFunction(Func func) { auto lambda = [=](std::shared_ptr<Base>& ptr)->void { std::shared_ptr<Derived> d = std::dynamic_pointer_cast<Derived>(ptr); if (d) func(std::move(d)); }; functions.push_back(lambda); return true; } void dispatch(std::shared_ptr<Base>& ptr) { for(auto& func : functions) func(ptr); } private: std::vector<std::function<void(std::shared_ptr<Base>&)>> functions; }; FooDispatcher dispatcher; void foo( Base::Ptr ptr ) { dispatcher.dispatch(ptr); } class Derived1 : public Base { public: typedef std::shared_ptr < Derived1 > Ptr; }; void fooImpl1( Derived1::Ptr ptr ) { std::cout << "Came to fooImpl(Derived1::Ptr).\n"; } class Derived2 : public Base { public: typedef std::shared_ptr < Derived2 > Ptr; }; void fooImpl2( Derived2::Ptr ptr ) { std::cout << "Came to fooImpl(Derived2::Ptr).\n"; } int main() { dispatcher.registerFunction<Derived1>(fooImpl1); dispatcher.registerFunction<Derived2>(fooImpl2); Base::Ptr ptr(new Derived1); foo(ptr); ptr = Base::Ptr(new Derived2); foo(ptr); }更多推荐
动态指针
发布评论