2012-01-19 3 views
35

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

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?

+5

Это звучит, как вы уже поняли, ответ на этот вопрос ... –

+3

Как я уже сказал, я клянусь себе, что я пытался это раньше, и были проблемы. Когда это внезапно сработало, я хотел убедиться, что это было не просто потому, что я был на другом компиляторе, разных флажках предупреждения/ошибки и т. Д., И что он был определен - предпочтительно - что это было стандартно. – Anthony

+2

Кроме того, для чего это стоило, я не мог найти ничего онлайн, который окончательно сказал так или иначе. Какое лучшее место для размещения этой информации, чем SO? – Anthony

ответ

44

Шаблон класса действительно может содержать виртуальные или чистые виртуальные функции. Это было использовано Андреем Александресю в «Modern C++ Design» для реализации шаблона посетителя с использованием шаблонов и списков типов. Вы можете увидеть код here in his Loki library, если вам это интересно.

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

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

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

6

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

Да. Совершенно законный.

6

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

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

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

1

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

//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; 
}; 
Смежные вопросы