检查多态中的实变量类型(C ++)

时间:2009-04-16 15:02:12

标签: c++ polymorphism typechecking

假设我们有一个A类,B和C继承它。 然后我们创建一个对A的引用数组,并用B和C填充它。 现在我们决定要消除所有的C。有没有办法检查数组中每个字段的实际类型,而不执行像returnType()函数这样的冗余操作?

编辑:修复“A的数组”到“A的引用数组”。

5 个答案:

答案 0 :(得分:15)

你不能创建一个As数组并用Bs和Cs填充它们 - 它们将被分解为
  如。你可以创建一个指向A的指针数组,你可以使用指向B的指针和指向C的指针填充。

要在这种情况下检查某事物的类型 - 请使用动态强制转换:

    // create B or C randomly
    A * a = rand() % 2 ? new B : new C;

    if ( dynamic_cast <B *> ( a ) ) {
        // it's a B 
    }
    else {
        // it isn't (must be C in this case)
    }

答案 1 :(得分:3)

理想情况下,您想要弄清楚它是什么功能让您不希望Cs在那里。然后添加一个公开该属性的虚函数。这样,当您添加同样具有相同不需要的属性的D类时,事情将继续正常运行。

class A
{
public:
    virtual bool IsFrobbable() { return true; }
};

class B : public A
{
};

class C : public A
{
public:
    virtual bool IsFrobbable() { return false; }
};

int main()
{
     vector<A *> vA;
     vA.push_back(new A());
     vA.push_back(new B());
     vA.push_back(new C());

     vA.erase(remove_if(vA.begin(), vA.end(), not1(mem_fun(&A::IsFrobbable))));
     // Now go ahead and frob everything that's left
}

答案 2 :(得分:0)

您将无法将B存储在其中。编译器会呻吟。

答案 3 :(得分:0)

这只有在A的​​数组实际上是A的指针数组时才有效,否则你会遇到切片问题。

至于手头的问题,你最好给A一个虚函数getClassName,并在子类中适当地ovverriding它,然后用结果来提供你想要的行为。

答案 4 :(得分:0)

无法在C ++中创建引用数组。

但是,可以创建一个指向A的指针数组。在这种情况下,如果A声明了至少1个虚函数,则可以使用C ++的运行时类型推断(RTTI)机制来执行您想要执行的操作:

A* arr[10];

fill_with_as_bs_and_cs(arr);

for (int i = 0; i < 10; ++i) {
    if (dynamic_cast<C*>(arr[i])) {
        arr[i] = 0;   // You can't really "remove" things from an array...
    }
}

但是,这不是最易维护的方法 - 只要您需要区分CA,就需要使用此if测试,如果最后,您需要从A获取更多类,并且还需要以不同方式处理它们,您需要更新代码中执行此“类型测试”的每个位置。随着您的代码库变得越来越大,很快就会错过很多地方。

通常,使用在每个类中根据需要覆盖的虚函数更加可维护。在这种特殊情况下,确定应该从数组中删除的所有A派生类对象共享的通用标准 - 假设一个对象应该被删除 blargable - 然后编写虚拟函数bool isBlargable(),然后测试