Наследование по сравнению со специализацией

Я почти уверен, что вы не можете использовать значения параметров по умолчанию в JS, вот что, вероятно, ломает в IE.

Вместо этого вам нужно будет установить его по умолчанию:

processMessages: function(problem, container, useMessage) {
  if (typeof useMessage === 'undefined') useMessage = true;
}

8
задан 7 April 2009 в 00:03
поделиться

4 ответа

То, что Вы в конечном счете хотите, я думаю, должно сделать, чтобы пользователь ввел

Vector<T, N>

И в зависимости от N, пользователь получит небольшие разные вещи. Первое не выполнит это, но второе желание, на цене дублирования кода.

То, что можно сделать, должно инвертировать наследование:

template<typename T, size_t N> struct VectorBase 
{
};

template<typename T> struct VectorBase<T, 2>
{
};

template<typename T> struct VectorBase<T, 3>
{
};

template<typename T, size_t N> struct Vector : VectorBase<T, N>
{
};

И реализуйте несколько функций, которые зависят только от N, являющегося некоторым определенным значением в соответствующем базовом классе. Можно добавить защищенный деструктор в них, для предотвращения пользователей, удаляющих экземпляры Vector через указатели на VectorBase (обычно они даже не должны мочь назвать VectorBase: Поместите те основания в некоторое пространство имен реализации, как detail).

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

Еще одна идея состоит в том, чтобы использовать всего один класс и затем enable_if (использование boost::enable_if) включить или отключить их для конкретных значений N, или используйте преобразователь интервала к типу как это, которое является большим количеством simplier

struct anyi { };
template<size_t N> struct i2t : anyi { };

template<typename T, size_t N> struct Vector
{
    // forward to the "real" function
    void some_special_function() { some_special_function(i2t<N>()); }

private:
    // case for N == 2
    void some_special_function(i2t<2>) {
        ...
    }

    // case for N == 3
    void some_special_function(i2t<3>) {
        ...
    }

    // general case
    void some_special_function(anyi) {
        ...
    }
};

Тем путем это абсолютно очевидно для пользователя Vector. Это также не добавит пространства наверху для компиляторов, делающих пустую (довольно распространенную) оптимизацию базового класса.

12
ответ дан 5 December 2019 в 10:44
поделиться

Используйте наследование и частное наследование. И не используйте виртуальные функции. С тех пор с частным наследованием, Вы не имеете, - a, никто не сможет использовать указатель базового класса на полученный подкласс, и Вы не получите режущую проблему когда passinfg значением.

Это дает Вам лучший из обоих миров (и действительно это - как большинство библиотек реализует многие классы STL).

Из http://www.hackcraft.net/cpp/templateInheritance/ (обсуждающий станд.:: вектор, не Ваш Векторный класс):

vector<T*> как объявляют, имеет частную основу vector<void*>. Все функции, которые помещают новый элемент в вектор, такой как push_back(), вызовите эквивалентную функцию на этой частной основе, поэтому внутренне наш vector<T*> использует a vector<void*> для устройства хранения данных. Все функции, которые возвращают элемент из вектора, такой как front(), выполните a static_cast на результате вызывания эквивалентной функции на частной основе. Начиная с единственного способа получить указатель в vector<void*> (кроме сознательно опасных приемов), через интерфейс, предлагаемый vector<T*> безопасно статично бросить void* назад к T* (или void*& назад к T*&, и так далее).

В целом, если STL делает это как это, это походит на достойный образец для подражания.

4
ответ дан 5 December 2019 в 10:44
поделиться

При использовании шаблонной специализации слишком много, вероятно, необходимо заново продумать дизайн. Рассмотрение, что Вы скрываете его позади a typedef, Я сомневаюсь, что Вам нужен он.

0
ответ дан 5 December 2019 в 10:44
поделиться

Наследование следует использовать только для моделирования "is-a". Специализация была бы более чистой альтернативой. Если вам нужно или вы хотите использовать наследование по какой-либо причине, по крайней мере сделайте его частным или защищенным наследованием, чтобы вы не наследовали публично от класса с общедоступным невиртуальным деструктором.

Да, ребята из метапрограммирования шаблонов всегда выполняются

 struct something : something_else {};

Но эти something являются метафункциями и не предназначены для использования в качестве типов.

0
ответ дан 5 December 2019 в 10:44
поделиться
Другие вопросы по тегам:

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