これを解決するにはかなり多くのバリエーションがありますが、まず第一に、仮想関数には同じ署名が必要です (例外がある可能性がありますが、それはあなたのケースには関係ありません)。したがって、解決策は、すべてのケースを解決する引数を持つことです。バリアントがあります:
すべてのバリアントを関数に渡し、特定のバリアントのみを使用します。
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 に仮想デストラクタは必要なくなりますが、安全性は低くなります。
これらはほんの一部のバリアントであり、プログラムの要件に基づいてのみ決定できる最も適したものは他にもある可能性があります.