c++ - todas - especificador puro en la definición de la función
tipos de funciones en lenguaje c (6)
Al compilar en GCC obtengo el error: pure-specifier en definición de función , pero no cuando compilo el mismo código usando VS2005.
class Dummy {
//error: pure-specifier on function-definition, VS2005 compiles
virtual void Process() = 0 {};
};
Pero cuando la definición de esta función virtual pura no está en línea, funciona:
class Dummy
{
virtual void Process() = 0;
};
void Dummy::Process()
{} //compiles on both GCC and VS2005
¿Qué significa el error? ¿Por qué no puedo hacerlo en línea? ¿Es legal evadir el problema de compilación como se muestra en la segunda muestra de código?
Estándar de C ++, 10.4 / 2:
una declaración de función no puede proporcionar un especificador puro y una definición
Esta sintaxis:
virtual void Process() = 0 {};
no es legal C ++, pero es compatible con VC ++. Exactamente por qué el estándar no permite esto nunca ha sido obvio para mí. Tu segundo ejemplo es legal.
Esto está gramaticalmente prohibido: el declarador que puede incluir especificadores puros , es decir, el miembro declarador , solo aparece en declaraciones que no son definiciones. [class.mem]:
declaración de miembro :
attribute-specifier-seq opt decl-specifier-seq opt member-declarator-list opt;
función-definición
[...]miembro-declarator-list :
miembro declarador
member-declarator-list , member-declaratormiembro declarador :
declarador virt-specifier-seq opt purificador-especificador opt
declarator corchete-o-igual-inicializador opt
identificador opt atributo-especificador-seq opt:
expresión constante
La gramática de función-definición no incluye un especificador puro , [dcl.fct.def.general]:
función-definición :
atributo-especificador-seq opt decl-especificador-seq opt declarator virt-especificador-seq opt función-cuerpo
Las funciones virtuales puras en C ++ por definición no tienen definición en la declaración .
El segundo bloque de código no está evitando el problema del compilador. Está implementando una función virtual pura de la manera que se pretendía.
La pregunta es, ¿por qué necesita declararla puramente virtual si tiene la intención de tener una implementación predeterminada?
Ok, acabo de aprender algo. Una función virtual pura debe declararse de la siguiente manera:
class Abstract
{
public:
virtual void pure_virtual() = 0;
};
Puede tener un cuerpo, aunque es ilegal incluirlo en el punto de declaración. Esto significa que para tener un cuerpo, la función virtual pura debe definirse fuera de la clase. Tenga en cuenta que incluso si tiene un cuerpo, la función aún debe ser anulada por cualquier clase concreta derivada de Abstract
. Simplemente tendrían la opción de llamar a Abstract::pure_virtual()
explícitamente si fuera necesario.
Los detalles están here .
Sin duda puede proporcionar un cuerpo para la función virtual pura. Esa función será señalada por esa clase abstracta vtable. De lo contrario, la misma ranura apuntará a la función de captura específica del compilador, como __cxa_pure_virtual
para GCC. Por supuesto, no hay nada sobre esto en el estándar.