Определение статического метода, делегированного производному классу (c ++) - PullRequest
1 голос
/ 02 февраля 2011

В прошлом году я видел некоторый исходный код (C ++), где его автор объявляет статическую функцию в базовом классе, но оставляет ее определение производному классу.Я помню, что было ограничение, что только одному производному классу было разрешено определять вышеупомянутую статическую функцию.

Я знаю, что невозможно переопределить статические методы, но этот прием - именно то, что мне нужно.Я просто не могу заставить его работать в моем коде :) Кто-нибудь знает об этой функции?

Давайте посмотрим, почему это было бы полезно.Предположим, у нас есть некоторый базовый класс (Shape) и его производные классы (Circle, Triangle ...).Предположим, Shape является частью моей базовой архитектуры, а производные классы рассматриваются как плагины.Я не хочу менять свою основную архитектуру в будущем.Итак, мы имеем:

class Shape
{
    //other stuff here
    static Shape* Factory();
}

class Circle:Shape
{
    //other stuff here
    static Shape* Factory();
}

Shape - это своего рода абстрактный класс, и он не будет реализовывать метод Factory.Метод реализован одним (и только одним) из производных классов.В реализации производный класс будет возвращать новый экземпляр самого себя, так что это просто фабричный метод.Этот трюк позволил его автору использовать этот статический метод в клиентском классе следующим образом:

class Client
{
    public Shape* shape;
    public Client();
    //other stuff here
}

В реализации конструктора у него было что-то вроде:

Client::Client()
:shape(Shape::Factory())
{        
}

Таким образом, он смогсоздать «правильную» форму, не меняя базовые классы в движке.Когда он хотел, чтобы в базовых классах использовалась какая-то другая фигура, ему просто нужно было определить статический метод Factory в этом производном классе (и удалить существующий в другом производном классе).

Таким образом, мы имеем некоторый "статический полиморфизм".Я не могу найти ничего об этой технике в Интернете.У него даже есть имя?Меня особенно интересует, может ли что-то подобное быть достигнуто на языке C #?:)

Заранее спасибо, и извините за мой плохой английский.

Ответы [ 2 ]

0 голосов
/ 02 февраля 2011

То, что вы пытаетесь сделать, на мой взгляд, немного грязно.Это похоже на комбинацию класса Factory, Singleton, а затем попытки вернуть их обратно в иерархию классов результатов.

Самое простое (не обязательно лучшее) решение, которое я могу придумать, это забыть о том, чтобыCircle::Factory() или Shape::Factory() и просто иметь бесплатную функцию с именем get_default_shape().

class Shape
{
};

class Circle: public Shape
{
};

Shape * get_default_shape()
{
  return new Circle;
}

Client::Client()
:shape(get_default_shape())
{
}

Приятно, что это только реализация get_default_shape, которая должна включать в себя Circle.h, всеОпределение потребности - это предварительное объявление класса Shape.

0 голосов
/ 02 февраля 2011

Хм. Я не видел точно, что вы описываете. Возможно, фрагмент кода, на который вы ссылаетесь, определил статическую функцию базового класса в файле cpp, содержащем ваш производный класс.

// definition of Circle class
.....

Shape* Shape::Factory()
{
     return new Circle();
}

В этом примере это бесполезно, но может оказаться полезным, если вы хотите скрыть реализацию класса и опубликовать только абстрактный базовый класс (чтобы уменьшить зависимости времени компиляции). Это не будет работать, если базовый и производный классы не находятся в одной и той же dll / exe.

Подобные вещи могут быть достигнуты в C # с помощью инфраструктуры IOC, с обобщениями или путем регистрации фабрики delegate в базовом классе. Я предпочитаю дженерики и делегаты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...