0

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

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>...
}

}

4

3 回答 3

3

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

于 2013-09-04T19:05:01.820 回答
0

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;
  }
}
于 2013-09-04T19:02:18.390 回答
0
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);

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

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

于 2013-09-04T19:03:04.183 回答