2

假设我们有一个类 A 和类 B 和 C 继承自它。然后我们创建一个对 A 的引用数组,并用 B 和 C 填充它。现在我们决定要消除所有的 C。有没有一种方法可以检查数组的每个字段真正拥有的类型,而无需执行诸如 returnType() 函数之类的冗余操作?

编辑:将“A 的数组”固定为“A 的引用数组”。

4

5 回答 5

15

您不能创建一个 As 数组并用 Bs 和 Cs 填充它 - 它们将被切成
As。您可以创建一个指向 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)
    }
于 2009-04-16T15:03:07.657 回答
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
}
于 2009-04-16T15:09:35.847 回答
0

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

于 2009-04-16T15:06:13.967 回答
0

这仅在 A 的数组实际上是指向 A 的指针数组时才有效,否则您将遇到切片问题。

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

于 2009-04-16T15:07:41.843 回答
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...
    }
}

然而,这不是最容易维护的方法——任何时候你需要区分 aC和 anA时,你都需要使用这个if测试,如果你最终派生了更多的类A并且你还需要区别对待它们,你将需要更新代码中执行此“类型测试”的每个位置。随着您的代码库变得越来越大,很快就会很容易错过一些地方。

通常,根据需要使用在每个类中重写的虚函数更易于维护。在这种特殊情况下,确定应该从数组中删除的所有派生类对象共享的一般标准A是什么——假设一个对象如果是blargable则应该被删除——然后编写一个虚函数bool isBlargable(),并测试相反

于 2009-04-16T15:20:29.273 回答