假设我们有一个A类,B和C继承它。 然后我们创建一个对A的引用数组,并用B和C填充它。 现在我们决定要消除所有的C。有没有办法检查数组中每个字段的实际类型,而不执行像returnType()函数这样的冗余操作?
编辑:修复“A的数组”到“A的引用数组”。
答案 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...
}
}
但是,这不是最易维护的方法 - 只要您需要区分C
和A
,就需要使用此if
测试,如果最后,您需要从A
获取更多类,并且还需要以不同方式处理它们,您需要更新代码中执行此“类型测试”的每个位置。随着您的代码库变得越来越大,很快就会错过很多地方。
通常,使用在每个类中根据需要覆盖的虚函数更加可维护。在这种特殊情况下,确定应该从数组中删除的所有A
派生类对象共享的通用标准 - 假设一个对象应该被删除 blargable - 然后编写虚拟函数bool isBlargable()
,然后测试 。