C# 的 C++ 模拟"is"关键字

c++ analog of c# "is" keyword

本文关键字:is 关键字 模拟 C++      更新时间:2023-10-16

我正在将这个c#代码重写为c++:

foreach (var index in indexes)
{
    if (index is MaWorker)
    {
        (index as MaWorker).needCalculate = true;
    }
    if (index is RocWorker)
    {
        (index as RocWorker).needCalculate = true;
    }
}

什么是最好的c++模拟?我应该使用什么来代替C#is关键字?

C++11也有foreach和自动类型推理。因此,假设您有一个现代编译器并启用了C++11:

for (auto index : indexes)
{
    if (auto w = dynamic_cast<MaWorker*>(index))
    {
        w->needCalculate = true;
    }
    if (auto w = dynamic_cast<RocWorker*>(index))
    {
        w->needCalculate = true;
    }
}

请注意,对每个指针使用isas。它们都会检查对象的动态类型,但您只需要检查一次。幸运的是,C++有这种带有声明的条件语法。

最好的c++模拟是使用std::shared_ptr和std::dynamic_pointer_cast。这是因为在c#中,所有对象实际上都是引用计数句柄,而在c++中,它的模拟对象是shared_ptr。

所以:

class Worker {};
class MaWorker : public Worker {};
class RocWorker : public Worker {};
std::vector< std::shared_ptr< Workers > > indexes;
for (const auto& index : indexes) {
  if (auto ma = std::dynamic_pointer_cast<MaWorker>(index)) {
    ma->needCalculate = true;
  }
  if (auto roc = std::dynamic_pointer_cast<RocWorker>(index)) {
    roc->needCalculate = true;
  }
}

然而,这种对类类型的切换打破了OO原则。为什么不将needCalculate成员移到基类中,或者更好地使用一些基类方法来通知对象您正在处理的任何外部事件?也许这超出了转换的范围。

不过要小心。c#对象引用与c++指针不同。