如何在其他类中访问子类函数?统计数组中B类对象数的方案是否正确?
问题解答
你的getType虚函数实现是否正确?
这种实现是完全正确的,能顺利统计出数组中B类对象的数量。具体来说,你只需要在基类A里把getType声明为纯虚函数,让B、C各自实现返回对应的标识,然后在D类里遍历数组,通过判断返回值来计数就行。
不过这种方式也有几个小问题:
- 扩展性差:要是以后加新的子类,不仅要给新类加
getType实现,还得修改统计函数里的判断逻辑,容易漏改; - 容易出错:字符标识比如
'b'、'c'要是写错(比如大小写搞混),直接就会统计错误; - 不符合开闭原则:新增类型就得修改原有统计代码,不是最优的设计方式。
其他判断类型/访问子类函数的方法
1. 用dynamic_cast做类型检查
C++里的dynamic_cast可以用来判断指针是否指向某个子类对象,直接用它来统计就行:
int countB(A* aArray[], int size) { int count = 0; for (int i = 0; i < size; ++i) { // 转换成功说明当前对象是B类(或B的子类) if (dynamic_cast<B*>(aArray[i])) { count++; } } return count; }
这种方法不用修改原有类的结构,新增子类也不用改统计逻辑,缺点是dynamic_cast有一点点运行时开销,但对于20个元素的数组来说完全可以忽略。
2. 新增专门的类型判断虚函数
直接在基类A里加一个纯虚函数isB,让子类各自实现:
// 基类A class A { public: virtual bool isB() const = 0; virtual ~A() = default; // 基类必须加虚析构,防止内存泄漏 }; // B类 class B : public A { public: bool isB() const override { return true; } }; // C类 class C : public A { public: bool isB() const override { return false; } };
然后D类的统计函数直接调用isB()判断:
int countB() { int count = 0; for (int i = 0; i < 20; ++i) { if (aArray[i]->isB()) { count++; } } return count; }
这种方式语义更直接,运行时开销也小,但如果以后要统计多种类型,就得加多个类似isC的虚函数,扩展性一般。
3. 访问者模式(适合复杂场景)
如果以后还有很多和类型相关的操作,比如统计C的数量、对B做特定处理等,可以用访问者模式,把操作和类本身分离:
先定义访问者基类和接受访问的接口:
// 前向声明子类 class B; class C; class Visitor { public: virtual void visit(B* b) = 0; virtual void visit(C* c) = 0; }; class A { public: virtual void accept(Visitor& visitor) = 0; virtual ~A() = default; }; class B : public A { public: void accept(Visitor& visitor) override { visitor.visit(this); } }; class C : public A { public: void accept(Visitor& visitor) override { visitor.visit(this); } };
然后写一个统计B数量的访问者:
class BCountVisitor : public Visitor { private: int count = 0; public: void visit(B* b) override { count++; } void visit(C* c) override { // 对C不做处理 } int getCount() const { return count; } };
D类里这么用:
int countB() { BCountVisitor visitor; for (int i = 0; i < 20; ++i) { aArray[i]->accept(visitor); } return visitor.getCount(); }
这种方式扩展性很好,新增子类或新操作都不用改原有类,但实现起来有点复杂,要是只是简单统计数量的话,有点大材小用。
内容的提问来源于stack exchange,提问作者serkan ertas
相关产品推荐
相关产品推荐

