Реализовать виртуальный метод из базового класса как производный от статического
У меня есть абстрактный базовый класс с виртуальным методом. В производном классе этот метод реализован. Однако я хочу, чтобы функция в производном классе была статическим методом, чтобы можно было вызывать функцию без создания экземпляра объекта этого класса.
class Base
{
virtual double Foo(double rParam) const;
};
class Derived1 : public Base
{
static double Foo(double rParam);
};
class Derived2 : public Base
{
static double Foo(double rParam);
};
По сути, Derived1 и Derived2 предоставляют разные реализации статической функции (которые не зависят от данных объекта), но я хочу, чтобы эти функции были виртуальными, чтобы иметь возможность вызывать эти функции в других функциях базового класса. Единственное решение, которое я вижу сейчас, - реализовать две функции-члена в производном классе, одна из которых является виртуальной функцией из базового класса, а другая (с другим именем) является статической функцией. Чтобы предотвратить дублирование исходного кода, виртуальная функция может затем напрямую вызывать статическую функцию (может быть встроенной). Любые другие решения?
class Derived : public Base
{
double Foo(double rParam)const
{
return FooStatic(rParam);
}
inline static double FooStatic(double rParam);
};
2 ответа
Я думаю, что FooStatic
подход, который у вас есть, - лучший способ сделать это с точки зрения соблюдения хорошей ОО-практики. По сути, ваш нестатический Foo
переопределения работают как статические указатели на ваши статические версии.
(Акцент на "работать как": вы не можете напрямую использовать указатели на функции, так как переопределение для Foo
должен выбросить ссылку на this
перед вызовом FooStatic
.)
Не имеет смысла делать виртуальный метод статичным. Виртуальный означает, что вы выбираете, какую реализацию запускать, основываясь на типе объекта. В статическом контексте у вас нет объекта.
РЕДАКТИРОВАТЬ: Хотя первый пример будет скомпилирован, он не будет делать то, что вы ожидаете. Статические методы не будут переопределять базовую реализацию, а скорее скрывать ее, а это означает, что статические методы никогда не будут вызываться вместо базового класса. Второй пример хорошо, хотя я не вижу никаких проблем с ним.