You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在其他类中访问子类函数?统计数组中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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 20:20:58