如何检查派生类中对象的类型名称?

时间:2010-05-05 15:20:35

标签: c++

这是我的代码:

class Base { /* something */ };
class Derived : public Base { /* something */ };
vector<Base*> v; // somebody else initializes it, somewhere
int counter = 0; 
for (vector<Base*>::iterator i=v.begin(); i!=v.end(); ++i) {
  if (typeof(*i) == "Derived") { // this line is NOT correct
    counter++;
  }
}
cout << "Found " << counter << " derived classes";

代码中的一行不正确。我该怎么写得好呢?非常感谢提前!

6 个答案:

答案 0 :(得分:5)

使用dynamic_cast:

if ( dynamic_cast <Derived*>( *i) ) { 
    counter++;

为了使其工作,您需要为您的基类提供至少一个虚函数 - 无论如何它确实需要一个虚拟析构函数。

答案 1 :(得分:5)

typeid的名称是实现定义的,您不应该对它们做出假设。但是,您可以比较两个typeid。

if typeid(**i) == typeid(Derived)

通常它会被认为是一个糟糕的设计(但如果目的只是编写一个不太实用的程序来计算Derived的实例,那就没关系了。)

请注意,这也要求Base有一个vtable(虚函数和/或析构函数),因为非多态类型只是没有typeid检查的动态类型(也就是说,它们都是Base的实例与typeid有关。)

如果您没有任何虚拟功能,那么您需要自己模拟。例如,如果您喜欢字符串比较并且不介意开销,请向Base添加一个字段,每个类型将在其构造函数中填写并比较这些字段。否则,为每个子类型等使用唯一的整数标识符。

答案 2 :(得分:0)

我认为typeof仅适用于C#。

SO帖子“How to typeof in C++”可能有用......

<强>更新 This可能有用:

  

运营商AFAIK是海湾合作委员会   延期。它不再适用   GCC 3.2.3中的模板化对象。   错误报告:   http://gcc.gnu.org/bugzilla/show_bug.cgi?id=9459

     

发布更改:   http://www.gnu.org/software/gcc/gcc-3.2/changes.html

     

目前GCC似乎真的有   难以确定的类型   模板功能甚至在合法的   情况...

我认为GCC支持__typeof__运营商。

正如其他人所说,我猜你可以用typeid代替。

答案 3 :(得分:0)

查看typeid运营商。

一般来说,使用它被认为是个坏主意。

答案 4 :(得分:0)

您可以使用typeid(包括<typeinfo>):

if (typeid(**i) == typeid(Derived))

或者您可以使用动态广告:

if (dynamic_cast<Derived*>(*i) != 0)

但通常应避免使用这两个代码,以支持被调用的虚函数,并且该函数被重写以对每种类型执行适当的操作。

答案 5 :(得分:0)

我想你想要:

for (...) {
   if (dynamic_cast<Derived*>(*i)) {
     counter++;
   }
}

的dynamic_cast&LT;&GT;尝试将基类指针转换为派生类指针。如果对象属于派生类型(或其子类),则返回正确的指针。如果它不是派生类型,则返回'nil'表示转换无法成功完成。