好的,是的,您应该如上所述使用多态性。如果您的函数需要处理 2 个对象,尽管它变得非常复杂。
如果派生形成一个有限的集合并且彼此了解,则可以使用双重调度。它并不完美,但它解决了这种特殊情况。
class DerivedA;
class DerivedB;
class DerivedC;
class BaseClass
{
public:
virtual ~BaseClass();
virtual void doSomethingWithBase( BaseClass & b2 ) = 0;
virtual void doSomethingWithDerivedA( DerivedA & da ) = 0;
virtual void doSomethingWithDerivedB( DerivedB & db ) = 0;
virtual void doSomethingWithDerivedC( DerivedC & dc ) = 0;
};
class DerivedA : public BaseClass
{
public:
void doSomethingWithBase( BaseClass & b2 )
{
b2.doSomethingWithDerivedA( *this );
}
void doSomethingWithDerivedA( DerivedA & da )
{
// implement for two DerivedA objects
}
void doSomethingWithDerivedB( DerivedB & db )
{
// implement for an A and B
}
void doSomethingWithDerivedC( DerivedC & dc )
{
// implement for an A and C
}
};
// implement DerivedB to call doSomethingWithDerivedB on its parameter
// implement DerivedC to call doSomethingWithDerivedC on its parameter.
你明白了。从你打电话的地方你不需要知道你有哪两种类型,你也不需要实际查找。但是,如果您添加了更多的实现,您将需要编辑大量代码,并且可能会考虑使用某种查找表。
如果你需要一个类来定义自己,你可以使用某种虚拟 id。
class BaseClass
{
public:
virtual int id() const = 0;
};
然后让类显示它们的 id 并根据这些 id 在表中找到处理这两个对象的处理程序。id 不必是整数,它们可以是字符串,这样更容易避免命名冲突,这比不知道其派生类或它们彼此认识的基类的双重调度方法具有优势,并且是可扩展的。您也不必处理每一对。