相近:
std::shared_ptr<Tiger> t = ...; session.store("tigers/1",t); std::shared_ptr<Tiger> t2 = session.load<Tiger>("tigers/1");
两个函数定义为:
class Session { template<class T> voID store(std::string ID,std::shared_ptr<T> instance); template<class T> std::shared_ptr<T> load(std::string ID); }
请注意,会话可以存储异构类型,但在存储和加载时,我静态地知道变量的类型是什么.
我的问题是我遇到了这样一种情况:用户想要将Tiger放入会话中,而是检查基本类型.例如:
session.load<Animal>("tigers/1");
现在,我实际上将数据作为voID *存储在会话中,并使用reinterpret_cast将它们恢复为用户提供的类型.只要一切都是微不足道的,这就行……但是当我们遇到稍微复杂的情况时,我们会遇到问题.
以下是演示我的问题的完整代码:
struct Animal{ virtual voID Pet() const = 0;};struct IJumpable{ virtual voID Jump() const = 0;};struct Tiger : Animal,IJumpable{ voID Pet() const overrIDe { std::cout << "Pet\n"; } voID Jump() const overrIDe { std::cout << "Jump\n"; }};int main(){ auto cat = std::make_shared<Tiger>(); // how the data is stored insIDe the session auto any_ptr = std::static_pointer_cast<voID>(cat); // how we get the data out of the session auto namable = std::static_pointer_cast<IJumpable>(any_ptr); namable->Jump(); std::cout << std::endl;}
如果您运行此代码,您将看到它运行,但它不是调用Jump,而是调用Pet.我知道这是因为使用了错误的虚方法表,因为我实际上在`voID *上调用了reinterpret_cast.
我的问题是,如果有一个很好的方法来处理C中的这种情况.我环顾四周,没有看到任何符合我需要的东西.
我发现的异构容器的所有内容总是假设一个共享的基类,我没有也不想要.这可能吗?
解决方法 解决方案由我的兄弟提供,恰好是没有stackoverflow的C专家:)这是一个voID_ptr实现,它使用异常处理实现多态转换以发现类型.性能应该接近dynamic_cast的性能.您应该能够使用std :: type_index优化上述内容并缓存偏移量.
#include <stdio.h>class voID_ptr { voID* obj; voID (*discover_type)(voID*); template<typename T> static voID throw_typed_object(voID* obj) { T* t = static_cast<T*>(obj); throw t; }public: voID_ptr() : obj(0) {} template<typename T> voID_ptr(T* t) : obj(t),discover_type(throw_typed_object<T>) { } template<typename T> T* cast() const { try { discover_type(obj); } catch(T* t) { return t; } catch(...) { } return 0; }};struct Animal { virtual ~Animal() {} virtual const char* name() { return "Animal"; }};struct Speaker { virtual ~Speaker() {} virtual const char* speak() { return "hello"; }};struct lion : public Animal,public Speaker { virtual const char* name() { return "lion"; } virtual const char* speak() { return "Roar"; }};int main(){ voID_ptr ptr(new lion()); Animal* a = ptr.cast<Animal>(); Speaker* s = ptr.cast<Speaker>(); printf("%s\n",a->name()); printf("%s\n",s->speak());}总结
以上是内存溢出为你收集整理的c – 来自空隙的多晶铸造*全部内容,希望文章能够帮你解决c – 来自空隙的多晶铸造*所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)