Шаблонный полиморфизм может использоваться вместо полиморфизма OO?

Большие играющие студии, вероятно, не примут XNA в ближайшее время. Некоторые инди используют его, но определенно имеет потенциал, чтобы в конечном счете быть очень успешным и оставить C++.

XNA обеспечивает много классов, которые можно использовать в разработке игр, но многие другие часто принимают решение использовать полностью оперенный игровой механизм. Хотя XNA довольно хорош для новичка для получения первый опыт в том, если Вы плохо знакомы с программированием игр.

C# является хорошим языком для использования для игровой разработки. Игровая разработка производит приложения, которые требуют звуковой, усовершенствованной графики, AI, Физики, и т.д. Все, что требует мощной и довольно быстрой языковой среды. В то время как большая часть ПК высшего ранга и консольных игр записаны в C++, C# имеет план действий, который, вероятно, оставит C++. Ближайшие изменения в C++ 0x несомненно повторно поддержат C++ на некоторое время, но C# выглядит готовым настигнуть его.

, Если бы Вы действительно хотите быть игровым разработчиком, я убедил бы Вас, по крайней мере, изучить C++ и записать Ваш собственный игровой механизм. Используя предварительно сделанную игру механизм легок, и можно кодировать что-то, что является 'хорошо', но Вы столкнетесь со многими ограничениями, которые Вы не будете в состоянии кодировать вокруг. Вы будете эффективно ограничены возможностями игрового механизма (если у Вас не будет доступа к источнику, который Вы могли тогда изменить к своей симпатии).

Изучают C++ и предпочтительно OpenGL:), Как только Вы знаете OpenGL, можно изучить DirectX довольно легко.

C# является куском пирога, как только Вы знаете C++.

22
задан sth 2 August 2009 в 14:56
поделиться

3 ответа

Шаблоны обеспечивают статический полиморфизм: вы указываете параметр шаблона во время компиляции, реализуя стратегию. Они не обеспечивают динамический полиморфизм, когда вы предоставляете объект во время выполнения с виртуальными функциями-членами, которые реализуют стратегию.

В вашем примере кода шаблона будет создано три разных класса, каждый из которых содержит весь код Интерполатора, скомпилированный с использованием другого шаблона. параметры и, возможно, встраивание кода из них. Вероятно, это не то, что вы хотите от точки зрения размера кода, хотя в этом нет ничего категорического неправильного. Предположим, что вы выполняли оптимизацию, чтобы избежать накладных расходов на вызов функций, тогда это могло бы быть улучшением динамического полиморфизма. Скорее всего, это перебор. Если вы хотите использовать шаблон стратегии динамически, вам не нужны шаблоны, просто делайте виртуальные вызовы там, где это необходимо.

У вас не может быть переменной типа MyTemplate (за исключением того, что она появляется в другом шаблоне до его создания). MyTemplate и MyTemplate - совершенно не связанные классы (даже если X и Y связаны), которые, возможно, просто имеют схожие функции, если они созданы из один и тот же шаблон (а они не обязательно должны быть специализацией). Даже если это так, если параметр шаблона участвует в сигнатурах любой из функций-членов, тогда эти функции не совпадают, у них просто одинаковые имена. Итак, с точки зрения динамического полиморфизма, экземпляры одного и того же шаблона находятся в том же положении, что и любые два класса - они могут воспроизводиться только в том случае, если вы дадите им общий базовый класс с некоторыми виртуальными функциями-членами.

Итак, вы можете определить общий базовый класс:

class InterpolatorInterface {
public:
    virtual Value GetValue(const double) = 0;
    virtual void ConfigCache(const& ConfigObject) = 0;
    virtual void ConfigDataSource(const& ConfigObject) = 0;
    virtual ~InterpolatorInterface() {}
};

Затем :

template <typename TCacheStrategy, typename TDataSource>
class Interpolator: public InterpolatorInterface {
    ...
};

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

Кстати, это не метапрограммирование шаблонов, это просто использование шаблонов.

Edit . Что касается TMP, вот канонический вводный пример:

#include <iostream>

template<int N>
struct Factorial {
    static const int value = N*Factorial<N-1>::value;
};

template<>
struct Factorial<0> {
    static const int value = 1;
};

int main() {
    std::cout << "12! = " << Factorial<12>::value << "\n";
}

Обратите внимание, что 12! был вычислен компилятором и является константой времени компиляции. Это интересно, потому что оказывается, что система шаблонов C ++ - это полный по Тьюрингу язык программирования, а препроцессор C - нет. В зависимости от ограничений ресурсов вы можете выполнять произвольные вычисления во время компиляции, избегая накладных расходов времени выполнения в ситуациях, когда вы знаете входные данные во время компиляции. Шаблоны могут манипулировать своими параметрами шаблона как функциональный язык, а параметры шаблона могут быть целыми числами или типами. Или функции, хотя их нельзя «вызвать» во время компиляции. Или другие шаблоны, хотя они не могут быть «возвращены» как статические члены структуры.

s канонический вводный пример:

#include <iostream>

template<int N>
struct Factorial {
    static const int value = N*Factorial<N-1>::value;
};

template<>
struct Factorial<0> {
    static const int value = 1;
};

int main() {
    std::cout << "12! = " << Factorial<12>::value << "\n";
}

Обратите внимание, что 12! был вычислен компилятором и является константой времени компиляции. Это интересно, потому что оказывается, что система шаблонов C ++ - это полный по Тьюрингу язык программирования, а препроцессор C - нет. В зависимости от ограничений ресурсов вы можете выполнять произвольные вычисления во время компиляции, избегая накладных расходов времени выполнения в ситуациях, когда вы знаете входные данные во время компиляции. Шаблоны могут манипулировать своими параметрами шаблона, как функциональный язык, а параметры шаблона могут быть целыми числами или типами. Или функции, хотя их нельзя «вызвать» во время компиляции. Или другие шаблоны, хотя они не могут быть «возвращены» как статические члены структуры.

s канонический вводный пример:

#include <iostream>

template<int N>
struct Factorial {
    static const int value = N*Factorial<N-1>::value;
};

template<>
struct Factorial<0> {
    static const int value = 1;
};

int main() {
    std::cout << "12! = " << Factorial<12>::value << "\n";
}

Обратите внимание, что 12! был вычислен компилятором и является константой времени компиляции. Это интересно, потому что оказывается, что система шаблонов C ++ - это полный по Тьюрингу язык программирования, а препроцессор C - нет. В зависимости от ограничений ресурсов вы можете выполнять произвольные вычисления во время компиляции, избегая накладных расходов времени выполнения в ситуациях, когда вы знаете входные данные во время компиляции. Шаблоны могут манипулировать своими параметрами шаблона как функциональный язык, а параметры шаблона могут быть целыми числами или типами. Или функции, хотя их нельзя «вызвать» во время компиляции. Или другие шаблоны, хотя они не могут быть «возвращены» как статические члены структуры.

и является константой времени компиляции. Это интересно, потому что оказывается, что система шаблонов C ++ - это полный по Тьюрингу язык программирования, а препроцессор C - нет. В зависимости от ограничений ресурсов вы можете выполнять произвольные вычисления во время компиляции, избегая накладных расходов времени выполнения в ситуациях, когда вы знаете входные данные во время компиляции. Шаблоны могут манипулировать своими параметрами шаблона, как функциональный язык, а параметры шаблона могут быть целыми числами или типами. Или функции, хотя их нельзя «вызвать» во время компиляции. Или другие шаблоны, хотя они не могут быть «возвращены» как статические члены структуры.

и является константой времени компиляции. Это интересно, потому что оказывается, что система шаблонов C ++ - это полный по Тьюрингу язык программирования, а препроцессор C - нет. В зависимости от ограничений ресурсов вы можете выполнять произвольные вычисления во время компиляции, избегая накладных расходов времени выполнения в ситуациях, когда вы знаете входные данные во время компиляции. Шаблоны могут манипулировать своими параметрами шаблона, как функциональный язык, а параметры шаблона могут быть целыми числами или типами. Или функции, хотя их нельзя «вызвать» во время компиляции. Или другие шаблоны, хотя они не могут быть «возвращены» как статические члены структуры.

вы можете выполнять произвольные вычисления во время компиляции, избегая накладных расходов времени выполнения в ситуациях, когда вы знаете входные данные во время компиляции. Шаблоны могут манипулировать своими параметрами шаблона, как функциональный язык, а параметры шаблона могут быть целыми числами или типами. Или функции, хотя их нельзя «вызвать» во время компиляции. Или другие шаблоны, хотя они не могут быть «возвращены» как статические члены структуры.

вы можете выполнять произвольные вычисления во время компиляции, избегая накладных расходов времени выполнения в ситуациях, когда вы знаете входные данные во время компиляции. Шаблоны могут манипулировать своими параметрами шаблона, как функциональный язык, а параметры шаблона могут быть целыми числами или типами. Или функции, хотя их нельзя «вызвать» во время компиляции. Или другие шаблоны, хотя они не могут быть «возвращены» как статические члены структуры.

24
ответ дан 29 November 2019 в 04:57
поделиться

Я считаю, что шаблоны и полиморфизм хорошо работают вместе. В вашем примере, если клиентский код не заботится о том, какие параметры шаблона Интерполятор использует, тогда введите абстрактный базовый класс, который является подклассами шаблона. Например:

class Interpolator
{
public:
    virtual Value GetValue (const double) = 0;
};

template<class TCacheStrategy, class TDataSource>
class InterpolatorImpl : public Interpolator
{
public:
     InterpolatorImpl ();
     Value GetValue(const double);
};

void main()
{
    int param = 1;

    Interpolator* interpolator = 0;

    if (param==1)
        interpolator = new InterpolatorImpl<InMemoryStrategy,TextFileDataSource> ();
    else if (param==2)
        interpolator = new InterpolatorImpl<InMemoryStrategy,OdbcDataSource> ();
    else if (param==3)
        interpolator = new InterpolatorImpl<NoCachingStrategy,RestDataSource> ();

    while (true)
    {
        double input = WaitForRequest();
        SendRequest( interpolator->GetValue (input));
    }
}

Я довольно часто использую эту идиому. Он довольно хорошо скрывает шаблонный материал от клиентского кода.

Обратите внимание, я не уверен, что такое использование шаблонов действительно является классом как «метапрограммирование». Я обычно резервирую этот грандиозный термин для использования более сложных приемов шаблонов времени компиляции, особенно использования условных выражений, рекурсивных определений и т. Д. Для эффективного вычисления данных во время компиляции.

7
ответ дан 29 November 2019 в 04:57
поделиться

Шаблоны иногда называют статическим (или во время компиляции) полиморфизмом, поэтому да, иногда их можно использовать вместо ООП (динамического) полиморфизма. Конечно, это требует, чтобы типы определялись во время компиляции, а не во время выполнения, поэтому он не может полностью заменить динамический полиморфизм.

Когда я часто обнаруживаю, что хочу сделать, это иметь что-то вроде TemplateType x = new TemplateType (), где x не важно, что такое X, Y.

Да, это невозможно. Вы должны сделать что-то похожее на то, что у вас есть с функцией DoIt (). Часто я думаю, что это в любом случае приводит к более чистому решению (в итоге вы получаете более мелкие функции, каждая из которых выполняет только одно действие - обычно это хорошо). Но если типы определяются только во время выполнения (как с i в версии ООП вашей основной функции), то шаблоны не будут работать.

Но в этом случае я думаю, что ваша версия шаблона решает проблема, и это хорошее решение само по себе. (Хотя, как уже упоминалось, это означает, что код создается для всех трех шаблонов,

6
ответ дан 29 November 2019 в 04:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: