我有这样的声明:
struct InstrumentInfo
{
std::string Name;
TradingStatus Status;
myDecimal MinStep;
std::string ISIN;
myDecimal limit_down;
myDecimal limit_up;
};
struct FortsDerivativeInfo : InstrumentInfo
{
std::string ShortIsin;
int IsinId;
std::string CodeVcb;
myDecimal StepPrice;
int LotVolume;
myDecimal exch_pay;
};
struct StockInfo : InstrumentInfo
{
int LotSize;
};
我试图编写这样的代码:
if (auto si = dynamic_cast<StockInfo*>(ii))
{
LOT_SIZE = si->LotSize;
}
else
{
LOT_SIZE = 1;
}
这不编译,我收到“错误C2683:'dynamic_cast':'InstrumentInfo'不是多态类型”。我该如何解决这个错误?
如果我将dynamic_cast
替换为static_cast
代码编译,但由于static_cast
不执行任何运行时检查,我担心这不起作用?
答案 0 :(得分:2)
运行时类型信息仅适用于具有至少一个虚函数的类型(即&#34;多态类型&#34;)。使dynamic_cast
工作的唯一方法是使基本类型具有多态性 - 例如,通过声明其析构函数virtual
。
更好的方法是完全取消对强制转换的需求 - 例如,通过创建虚拟lotSize
函数:
struct InstrumentInfo
{
std::string Name;
TradingStatus Status;
myDecimal MinStep;
std::string ISIN;
myDecimal limit_down;
myDecimal limit_up;
virtual int lotSize() const { return 1; }
};
struct StockInfo : InstrumentInfo
{
int LotSize;
virtual int lotSize() const { return LotSize; }
};
InstrumentInfo ii;
LOT_SIZE = ii.lotSize();
答案 1 :(得分:0)
非多态类型(没有虚函数的类型)没有运行时类型信息。
在InstrumentInfo
中添加虚拟析构函数将为您提供RTTI并使dynamic_cast
正常工作,但解决问题的更好方法是,如另一个答案中所指出的,使用虚拟成员函数返回批量大小。不管RTTI如何使用虚拟析构函数都是个好主意,否则如果你这样做会有一些严重的问题:
InstrumentInfo * info = new FortsDerivativeInfo;
delete info;
这会导致未定义的行为(通过没有虚析构函数的基类指针删除派生对象)。
答案 2 :(得分:0)
简短的回答是:dynamic_cast
仅适用于多态类型,因此您必须寻找替代方案。
更长的答案是你有其他选择:
virtual
方法(基类的析构函数),你的代码将按原样编译virtual
方法,请创建一个可以避免这种丑陋演员的方法enum
,其指示当前实例化哪个子项;它们不是自动化的,因此是最后的追索权