有很多变体可以解决这个问题,但首先,虚函数必须具有相同的签名(可能有一个例外,但这与您的情况无关)。因此,解决方案是拥有可以解决所有情况的论点。有变种:
将所有变体传递给函数,并且只使用特定的一个:
class A {
public:
virtual void set( int, double ) = 0;
};
class B {
int y;
public:
virtual void set( int val, double ) { y = val; }
};
class C {
double y;
public:
virtual void set( int , double val ) { y = val; }
};
这不是很好的解决方案,也不能很好地扩展,所以我们可以使用联合:
Union Arg {
int i;
double d;
};
class A {
public:
virtual void set( Arg a ) = 0;
};
// derived classes are trivial, so omitted
Union 不是类型安全的,所以我们可以使用 boost::variant
另一种为参数设置另一个层次结构的解决方案:
struct Arg {
virtual ~Arg();
};
struct IntArg : Arg {
int m_value;
};
struct DoubleArg : Arg {
double m_value;
};
class A {
virtual void set( const Arg &a ) = 0;
};
class B {
int y;
public:
virtual void set( const Arg &a ) { y = dynamic_cast<const IntArg &>( a ).m_value; }
};
class C {
double y;
public:
virtual void set( const Arg &a ) { y = dynamic_cast<const DoubleArg &>( a ).m_value; }
};
您可以使用 static_cast ,然后在 Arg 中不需要虚拟析构函数,但这不太安全。
这些只是一些变体,可能还有更多,哪一个最适合您,您只能根据您的程序要求来决定。