1

Ожидаемый этот код, чтобы скомпилировать и работатьшаблона специализации чистого виртуального метода

template<class T> 
class Base 
{ 
    virtual void method() = 0; 
}; 

template<> 
void Base<int>::method() { std::cout << "overrided" << std::endl; } 

Base<int> base; 

Но это дает ошибку 'Base<int>': cannot instantiate abstract class. Частичная специализация, вызванная мыслью, сделает Base<int> не абстрактной и позволит ее создать.

Есть ли рабочее решение, такое же короткое, как этот, и что сохраняет абстракцию класса Base? В противном случае я могу сделать неабстрактный Base класса или не использовать решение Никола бола от сюда: Template specialization and inheritance

+0

Даже для обычного абстрактного класса вы можете иметь определение для чистой виртуальной функции. Но это не делает его менее абстрактным. Вы все равно не сможете создать экземпляр. – Arunmu

+2

@Arunmu Ответ лучше сформулирован как ответ, а не комментарий? –

+0

@AlanStokes Я согласен с вами, но я не думаю, что ответил на этот вопрос с этим комментарием. – Arunmu

ответ

4

Если это не сработает для класса, отличного от шаблона, почему он должен работать для класса шаблона?

#include<iostream> 

class Base 
{ 
    virtual void method() = 0; 
}; 

void Base::method() { std::cout << "overrided" << std::endl; } 

Base base; 

ошибки:

10 : error: cannot declare variable 'base' to be of abstract type 'Base' 
Base base; 
^ 
3 : note: because the following virtual functions are pure within 'Base': 
class Base 
^ 
8 : note: virtual void Base::method() 
void Base::method() { std::cout << "overrided" << std::endl; } 
^ 
Compilation failed 
+0

Спасибо за ответ. Я просто предположил, что определение чистых виртуальных функций делает абстрактные классы не абстрактными. –

2

насчет специализации всего класса (вместо только одной функции члена):

template<class T> 
struct TempClass 
{ 
    virtual void f() = 0; 
}; 

template <> 
struct TempClass<int> 
{   
    virtual void f() 
    { 
     //... 
    } 
}; 

Обратите внимание, что TempClass<int> нет дольше аннотация класс, но другие Base классы по-прежнему абстрактные классы, (TempClass<float>, TempClass<double>, TempClass<SomeClassType>, ...).

и

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

вы создадите базовый класс с полями, что и специализации имеют, а затем сделать эти шаблонные классы наследуют от базового класса:

template <typename T> 
struct Base 
{ 
    // some members that all Base classes have 
}; 


template <typename T> 
struct TempClass: Base<T> 
{ 
    virtual void f() = 0; 
}; 


template <> 
struct TempClass<int>: Base<int> 
{ 
    virtual void f() 
    { 
     //... 
    } 
}; 

Таким образом, уродливая копировальная паста не нужна.

+0

Вы говорите, что TempClass не будет содержать поля общего класса TempClass. Зачем? –

+0

@Aleksey Поскольку каждая спецификация шаблона * класса * рассматривается как отдельный (новый) шаблон класса. – PcAF

+0

спасибо за помощь, я думал, что специализация шаблона работает как наследование. –

0

можно обеспечить реализацию чистой виртуальной функции в классе. Это не делает класс актуальным.

class Base 
{ 
    virtual void method() = 0; 
}; 

void Base::method() { /* Do something */ } 

// This is still a problem since Base 
// is still an abstract class, i.e. it is not still not 
// instantiable. 
Base base; 
Смежные вопросы