确定C++类类型,无需反思/内省

Determine class type in C++ without reflection/introspection

本文关键字:内省 C++ 类型 确定      更新时间:2023-10-16

>我有一个名为A的接口类和两个实现A的基类B和C。 在我的代码中,我有时需要确定一个实例是 B 还是 C,并且我不希望有一个 A 的本地非静态成员来确定实现类是 B 类型还是 C。 出于性能原因,我也不想使用dynamic_cast或其他形式的反射来确定它们的类型。

是否建议为 A 创建一个基类 AA,该基类采用 int 类型的模板参数并使用该值来确定 B 或 C 的类型?

或者如何在 A 中定义一个静态方法,该方法返回一个被 B 和 C 中的类似方法遮蔽的枚举类型?

您是否试图避免使用虚函数?在这种情况下,您可以将该功能添加到 A 本身:

struct A {
    enum ClassType { ClassTypeB, ClassTypeC };
    const ClassType mClassType;
    ClassType classType() const
    { return mClassType; }
protected:
    A(ClassType type) : mClassType(type) { }
};

在子类中,您将使用如下内容初始化 A:

struct B: public A {
    B() : A(ClassTypeB) { }
};
struct C: public A {
    C() : A(ClassTypeC) { }
};
// ...
A* obj1 = new B;
A* obj2 = new C;
obj1->classType() == A::ClassTypeB; // true
obj2->classType() == A::ClassTypeC; // true

这使您可以避免任何虚拟方法调度,但缺点是A现在必须了解其子类。

每次我遇到这样的困境时,我都会使用访客模式。

编辑:

在您的情况下,您必须添加到 A:

virtual void visitMe(IVisitor *) = 0;

然后在每个类中实现它,如下所示:

void B::visitMe(IVisitor *visitor)
{
    visitor->visit(this);
}

在您的访客类中,您应该为每种类型添加"访问"功能:

struct Visitor: public IVisit
{
    void visit(B *);
    void visit(C *);
}

由于每种类型都有不同的访问功能,因此您可以通过调用以下命令来识别您正在使用的类型:

Visitor visitor;
C item;
item.visitMe(&visitor);    //visit for C will be used