【问题标题】:c++ can one turn a string value into a type?c ++可以将字符串值转换为类型吗?
【发布时间】:2013-09-04 18:44:10
【问题描述】:

我正在尝试编写一些通用代码:

int _pID = _plant->getPlantInternalID();
std::string _plantName = getPlantBasedUponInternalID(_pID);

_plantName 返回植物的字符串,如Broccoli

但是有没有办法做这样的事情:

for (int f=0; f < _f.getPlants().size(); f++)
{        
    std::shared_ptr<Plant> sbas = _f.getPlants().at(f);

    std::shared_ptr<_plantName> sder2 = std::dynamic_pointer_cast<_plantName>(sbas);
}

请注意,我输入的是 _plantName,但实际上我需要执行以下操作:

std::shared_ptr<Broccoli> sder2 = std::dynamic_pointer_cast<Broccoli>(sbas);    

什么需要做这样的事情,我该如何完成它?

更新:我只是根据我制作的内部 ID 获取 ID:

std::string HUDForStatus::getPlantBasedUponInternalID(int _id)
{
    switch (_id)
    {
        case 114: // Asparagus
            return ASPARAGUS::plantName.c_str();
            break;
        case 113: // Beets
            return BEETS::plantName.c_str();
            break;
        case 115: // Bok Choy
            return BOKCHOY::plantName.c_str();
            break;
        case 107: // Broccoli
            return BROCCOLI::plantName.c_str();
            break;
        case 101: // Carrot
            return CARROT::plantName.c_str();
            break;
        case 110: // Celery
            return CELERY::plantName.c_str();
            break;
        case 103: // Corn
            return CORN::plantName.c_str();
            break;
        case 116: // Eggplant
            return EGGPLANT::plantName.c_str();
            break;
        case 102: // Green Beans
            return GREENBEANS::plantName.c_str();
            break;
        ... <snip>...
}

}

【问题讨论】:

  • 所以 _plantName 是一个字符串,你想从中获取一个类型吗? getPlantBasedUponInternalID 如何确定要返回的字符串?我想如果您可以从 ID 中获取类型,那您为什么不这样做呢?
  • 我做了一个更新,你可以看到。所以你说的只是创建一个函数,它根据 ID 返回shared_ptr,就像我对字符串所做的那样。我没有想到,我猜很简单。
  • 为什么需要这个?为什么不能只使用 Plant* 类型的指针?
  • BROCCOLI 实际上是一个命名空间,我在其中存储了每个对象在创建时具有的一堆常量。
  • 如果有什么神奇的方法可以做到这一点,那么sder2-&gt;member是否可以编译将取决于运行时字符串_plantName

标签: c++ string object c++11


【解决方案1】:

这不是解决问题的 C++ 方法。相反,给Plant 一个适当的抽象接口,然后你就不需要知道你正在使用哪种具体类型。相反,您只需使用接口并让虚拟调度决定它是哪个工厂以及调用哪个实现。

【讨论】:

    【解决方案2】:
    std::shared_ptr<T> std::dynamic_pointer_cast<std::shared_ptr<U>& sp >
    

    只能在以下情况下工作

    dynamic_cast<T*>(sp.get()) 
    

    会起作用的。所以在你的情况下

    std::shared_ptr<_plantName> sder2 = std::dynamic_pointer_cast<_plantName>(sbas);
    

    Plant*std::string 的转换应该通过 dynamic_cast 有效。为此,std::string 应该从 Plant 派生,这也意味着这些类型应该是多态的(为此需要一些虚函数),因为 dynamic_cast 运算符使用从多态类生成的运行时类型信息。但这是不可能的。

    解决方案:

    1。 从Plant 派生你的类 - 然后像这样转换

    std::shared_ptr<Broccoli> sder2 = std::dynamic_pointer_cast<Broccoli>(sbas);
    

    将是可能的。 this 可能会有所帮助。

    2 。使用Plant 将实现的抽象接口。然后,您将使用该接口中的方法在运行时进行动态类型识别

    【讨论】:

    • 啊,西兰花是植物的一个子类。在 Plant Vector 中,我存储了 Broccoli、Asparagus 等对象,它们派生自基类 Plant。
    • 它必须是多态类型,为此需要一些虚函数
    【解决方案3】:

    c++ 是静态类型语言,不能在运行时创建一些随机类型的变量。如果你的类有一个通用接口,你可以这样做,如最后的示例所示。

    使用typeid 在运行时获取类型的唯一名称很容易。


    #include <iostream>
    #include <string>
    #include <typeinfo>
    #include <memory>
    
    struct B
    {
      virtual ~B(){}
      virtual void foo() = 0;
    };
    struct A1 : B
    {
      virtual void foo()
      {
        std::cout << 1 << std::endl;
      }
    };
    struct A2 : B
    {
      virtual void foo()
      {
        std::cout << 2 << std::endl;
      }
    };
    
    std::unique_ptr<B> getFooCaller( const std::string v )
    {
      if ( v==typeid(A1()).name() )
      {
        return std::unique_ptr<B>(new A1);
      }
      else if ( v==typeid(A2()).name() )
      {
        return std::unique_ptr<B>(new A2);
      }
    
      return 0;
    }
    
    int main(int argc, char* argv[])
    {
      if (argc!=2)
      {
        std::cout << "pass type name" << std::endl;
      }
    
      auto b = getFooCaller(argv[1]);
      if (b)
      {
        b->foo();
      }
      else
      {
        std::cout << "expecting  " << typeid(A2()).name() <<"  or  " << typeid(A2()).name() << std::endl;
      }
    }
    

    【讨论】:

    • 我会说静态类型,而不是强类型。
    • @DavidBrown 我会说它是一样的(见wiki)。或者,我错了吗?
    • 你的例子很有趣,但你没有像文章链接那样在任何地方使用typeinfo
    • @BЈовић - 我不需要你,只是指出你的解决方案与你的建议不同
    • @BЈовић 强类型和弱类型是模棱两可的术语(正如您链接的维基文章所说)。强类型有时意味着静态类型,但有时意味着类型安全。例如,python wikipedia article 说它是“强类型”。所以为了避免歧义,我通常使用静态或动态类型而不是强或弱。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-22
    • 2019-04-11
    • 1970-01-01
    • 1970-01-01
    • 2023-02-08
    • 1970-01-01
    相关资源
    最近更新 更多