我有一个名为 A 的接口类和两个实现 A 的基类 B 和 C。在我的代码中,我有时需要确定一个实例是 B 还是 C,我宁愿没有 A 的本地非静态成员确定实现类是 B 类型还是 C 类型。出于性能原因,我也不想使用 dynamic_cast 或其他形式的反射来确定它们的类型。
是否建议为 A 创建一个基类 AA,它采用 int 类型的模板参数并使用该值来确定 B 或 C 的类型?
或者如何在 A 中定义一个返回枚举类型的静态方法,该枚举类型被 B 和 C 中的类似方法所掩盖?
每次遇到这样的困境时,我都会使用访问者模式。
编辑:
在您的情况下,您必须添加到 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
您是否试图避免一般的虚拟功能?在这种情况下,您可以将该功能添加到 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
现在必须了解其子类。