1

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

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

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

4

2 回答 2

1

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

编辑:

在您的情况下,您必须添加到 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
于 2013-09-04T14:30:18.607 回答
1

您是否试图避免一般的虚拟功能?在这种情况下,您可以将该功能添加到 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现在必须了解其子类。

于 2013-09-04T14:56:00.117 回答