【问题标题】:How to write equivalent of Delphi "is" and "as" in C++ Builder?如何在 C++ Builder 中编写等效的 Delphi "is" 和 "as"?
【发布时间】:2018-10-08 07:32:52
【问题描述】:

我想编写一个函数(如果可能的话,甚至是一个运算符),它正在做类似于 Delphi 的“is”的事情。 德尔福示例:

 if Sender is TMenuItem then 
   TMenuItem(Sender)->Enabled = false;

因此,在 C++ Builder 中,这将类似于:

bool Is(*p1, *p2)
{
    p = dynamic_cast<p1*>(p2);      //here we typecast TObject to TMenuItem
    if (!!p)
    {
        return true;
    }
    else return false;
}

如何让函数接受 p1、p2 的任何类型的对象?

【问题讨论】:

  • 您只是想知道A 是否是B 的基类吗?如果是这样,请考虑std::is_base_of。如果您只想接受任意类型,请查找templates
  • 在 C++ 中,“正确”的方法是测试类,而是使用虚拟成员函数。
  • 我不明白为什么这个问题被否决:它的表述很好并且很有意义。仅仅因为 OP 想要的不是在 C++ 中进行的最佳方式,这并不意味着问题本身就是不好的。
  • @AGNGazer - 如果不赞成投票的人会因不张贴(评论或回答)的反对票而获得更高的“罚款”并且反对票不是匿名的,那么 SO 上的许多问题都将得到解决。跨度>
  • 不是反对者,但这个问题似乎很容易引发讨论(即我们是否应该尝试做这样的事情)。通常,如果我标记一个问题,我认为没有必要进一步解释它 - 如果我的标记有帮助,接近的理由就足够了,如果我的标记不正确,任何评论都将无效。

标签: c++builder


【解决方案1】:

问:如何让函数接受 p1、p2 的任何类型的对象?

答:使用模板,如下所示:

template<typename T, typename PtrType>
bool IsA(PtrType *ptr)
{
    return dynamic_cast<T*>(ptr) != nullptr;
}

像这样使用模板化函数:

A* obj = new C();
if (IsA<C>(obj))
{
        std::cout << "obj is of type C";
}

话虽如此,我建议您避免创建这样的函数,原因有两个:

  1. 您可以在任何地方使用 dynamic_cast,它更习惯用法,并显示您为进行此类检查所支付的成本
  2. 检查特定类型通常是设计有缺陷的标志。在某些情况下需要它,但这种情况很少见,总的来说,我个人认为不应宽恕它,这样的功能会这样做。

【讨论】:

  • 至第 2 点:是的,这是糟糕的 OO,但在这种情况下,您会传递一个声明类型为 (TObject *sender) 的指针,但实际上,它可以是,比如TMenuItem*TAction*,所以有时你必须强制转换。 -- 但我完全同意使用dynamic_cast 是这里的方法,因为即使例如IsA&lt;TMenuItem&gt;(Sender) 成功,要获得功能,你必须做一个dynamic_cast,无论如何,所以什么都没有保存。
  • 可能是这种情况——我没有使用过C++ Builder,所以我尽我所能回答了这个问题并给出了我的个人意见。我相信我的建议仍然有效:除非绝对需要,否则请避免动态转换。尝试将其使用限制在绝对需要的地方,这样它就不会在您的系统中到处传播。不要创建一个会促进它在任何地方都被使用的模式的函数。
  • 我认为风险没有那么大。 Delphi 有isas,实现了dynamic_cast 的两种用途。我几乎看不到任何真正滥用它的代码,或者它的使用渗透到整个代码的地方。它实际上只在适当和绝对必要的情况下使用。而且我看过很多的 Delphi 代码。
猜你喜欢
  • 2011-11-03
  • 1970-01-01
  • 2011-08-25
  • 1970-01-01
  • 2013-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多