我正在尝试编写一些通用代码:
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>...
}
}
答案 0 :(得分:3)
这不是C ++解决问题的方法。相反,给Plant
一个合适的抽象接口,然后你不需要知道你正在使用哪种具体类型。相反,您只需使用界面并让虚拟调度决定它是哪个工厂以及要调用哪个实现。
答案 1 :(得分: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;
}
}
答案 2 :(得分: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);
将是可能的。 this可能会有所帮助。
2。使用Plant
将实现的抽象接口。然后,您将使用此接口中的方法在运行时进行动态类型识别