Один из вариантов - явная перегрузка функции, а не использование аргументов по умолчанию.
class Base
{
public:
virtual void func() {func(2);} // call func(int) with one default
void func(int value);
};
class Derived: public Base
{
public:
using Base::func; // so the function which accepts an argument is
// not hidden from users the class
virtual void func() {func(42);} // call Base::func(int) with different value
};
В зависимости от необходимости, значением по умолчанию может быть проще использовать элемент, заданный конструктором.
class Base
{
public:
Base() : default_value(2) {};
void func() {func(default_value);}
void func(int value);
protected:
Base(int defaulted) : default_value(defaulted) {};
private:
int default_value;
};
class Derived: public Base
{
public:
Derived() : Base(42) {}; // set different default value in the constructor
};
В зависимости от ваших потребностей (и учитывая, что требуется только, чтобы функция снабжалась разными значениями по умолчанию, но в остальном они были одинаковыми), вы можете sh рассмотреть вопрос о том, чтобы оставить функции не виртуальными. .