Подтвердить что ты не робот

Разрешены ли чистые виртуальные методы внутри класса шаблона?

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

template <typename WordType> class DataSource
{
public:
    DataSource();
    DataSource(DataSource const& other);
    virtual ~DataSource();

    virtual void Put(
        WordType const* const data,
        unsigned int const wordCount) = 0;
}

Я попытался найти его в Интернете, и все, что я смог найти, это то, что вы не можете иметь виртуальный метод (чистый или иной) в обычном классе, например:

class DataSource
{
public:
    DataSource();
    DataSource(DataSource const& other);
    virtual ~DataSource();

    template <typename WordType>
    virtual void Put(
        WordType const* const data,
        unsigned int const wordCount) = 0;
}

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

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

В любом случае, снова задавая вопрос, если он там затерялся: Виртуальные (чистые и/или нормальные) виртуальные функции разрешены в классе tempate?

4b9b3361

Ответ 1

Шаблон класса действительно может содержать виртуальные или чистые виртуальные функции. Это было использовано Андреем Александресю в "Modern С++ Design" для реализации шаблона посетителя с использованием шаблонов и списков типов. Вы можете увидеть код здесь, в своей библиотеке Loki, если вам интересно.

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

Как вы уже упоминали, у вас не может быть функции виртуального шаблона, потому что количество слотов vtable не будет известно в блоке перевода.

Надеюсь, это поможет!

Ответ 2

Разрешены ли виртуальные (чистые и/или нормальные) виртуальные функции в классе tempate?

Да. Совершенно юридически.

Ответ 3

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

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

Когда мы фактически создаем экземпляр класса шаблона, например. DataSource<int>, то компилятору необходимо только создать виртуальную таблицу для выбранного вами типа, поэтому она не отличается от (чистой или иной) виртуальной функции для не templated класса.

Ответ 4

Шаблон класса с виртуальными функциями абсолютно прекрасен. Но функции шаблона с виртуальным ключевым словом, префиксным в классе или классе шаблона, недопустимы. Ниже вам поможет следующее:

//This is perfectly fine.
template <type T>
class myClass{
     virtual void function() = 0;
};

//This is NOT OK...
template<type T>
class myClass{
      template <type T>
      virtual void function() = 0;
};