c – 来自空隙的多晶铸造*

c – 来自空隙的多晶铸造*,第1张

概述有关详细信息,请参阅下面的代码,但基本方案如下所示.我有一个容器(会话),我可以放置对象和从中取出. 相近: std::shared_ptr<Tiger> t = ...; session.store("tigers/1", t); std::shared_ptr<Tiger> t2 = session.load<Tiger>("tigers/1"); 两个函数定义为: class Sess 有关详细信息,请参阅下面的代码,但基本方案如下所示.我有一个容器(会话),我可以放置对象和从中取出.

相近:

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 – 来自空隙的多晶铸造*所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1212264.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-04
下一篇 2022-06-04

发表评论

登录后才能评论

评论列表(0条)

保存