动态指针

编程入门 行业动态 更新时间:2024-10-24 20:18:58
本文介绍了动态指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我想将基类指针转换为派生类指针作为函数参数,而不使用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); }

更多推荐

动态指针

本文发布于:2023-07-31 15:40:25,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1260010.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:指针   动态

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!