Есть довольно много вариантов, чтобы решить эту проблему, но в первую очередь, виртуальная функция должна иметь одну и ту же подпись (может быть исключение, но это не имеет отношения к вашему делу). Поэтому решение состоит в том, чтобы иметь и аргументы (аргументы), которые разрешат все случаи. Есть варианты:
Проходят все варианты к функции, и использовать только частности один:
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
Союз не типобезопасен, поэтому мы можем использовать повышение :: вариант вместо
другое решение, чтобы иметь другую иерархию для параметра:
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, но это менее безопасно.
Это только некоторые варианты, их может быть гораздо больше, что подходит вам лучше всего, вы можете решить только на основе ваших требований к программе.
Создайте два отдельных класса без наследования? – juanchopanza
с наследованием. двумя баллонами являются B и C. – YkI
Было бы более целесообразно использовать шаблоны для этого, чем наследование – Chad