protegidos - polimorfismo puro c++
Funciones virtuales puras en C++ 11 (8)
Así es como se define la gramática, si miramos el borrador de la sección estándar de C ++ 9.2
Miembros de la clase, la gramática relevante es la siguiente:
[...]
member-declarator:
declarator virt-specifier-seqopt pure-specifieropt
[...]
pure-specifier:
= 0
^^^
La gramática indica específicamente que un especificador puro es = 0
y no un literal entero o expresión , que no parece dejar ningún margen de maniobra. Si intento cosas como:
virtual void foo() = 0L;
o:
virtual void foo() = NULL ;
gcc
me dice:
error: especificador puro no válido (solo ''= 0'' está permitido) antes '';'' simbólico
y clang
dice:
error: el inicializador de la función no se ve como un especificador puro
Aunque lo siguiente funciona en ambos:
#define bar 0
//...
virtual void foo() = bar;
También parece que clang
permite octal literal , hexadecmical literal y binario literal cero que es un comportamiento incorrecto.
Actualizar
Aparentemente Visual Studio
acepta NULL
y cualquier literal entero cero incluyendo 0L
, 0x0
, 00
etc ... Aunque no acepta nullptr
.
En C ++ 98, el puntero nulo estaba representado por el literal 0
(o de hecho, cualquier expresión constante cuyo valor era cero). En C ++ 11, preferimos nullptr
lugar. Pero esto no funciona para funciones virtuales puras:
struct X
{
virtual void foo() = nullptr;
};
¿Por qué esto no funciona? ¿No tendría sentido total? ¿Es esto simplemente un descuido? ¿Será arreglado?
El punto total de nullptr
(o la mayoría del punto de todos modos) es que solo se puede asignar (o usar para inicializar) punteros.
En este caso, no está inicializando o asignando un puntero, por lo que no tiene sentido que pueda usarlo en esta situación.
Eso no significa que sea un puntero, o que tenga que ser igual a nullptr
.
= 0
es suficiente y significa que la función virtual debe ser pura.
La gramática C ++ 11 solo permite 0
aquí (y no significa un puntero). Como nullptr
no es 0
, falla. NULL
solo funciona cuando NULL
se define como 0
(a veces es el caso, pero no siempre). Simplemente use 0
aquí, o use la siguiente definición (si realmente quiere usar un nulo, cuando no es un puntero).
#define VIRTUAL_NULL 0
struct X
{
virtual void foo() = VIRTUAL_NULL;
};
La notación = 0
para funciones virtual
no era literalmente "asignar nulo" sino una notación especial que es realmente engañosa: también se puede implementar una función virtual pura.
Con varias palabras clave de contexto, tendría más sentido permitir abstract
lugar de = nullptr
y hacer que abstract
sea una palabra clave de contexto.
La sintaxis = 0
no se usó para inicializar un puntero, sino simplemente para indicar sintácticamente que el virtual
proporcionado era puro.
Por lo tanto, la sintaxis = 0
para declarar s virtual
puros no se modifica.
Porque la sintaxis dice 0
, no expresión u otro nullptr
coincidente no terminal.
Por todo el tiempo solo 0
ha funcionado. Incluso 0L
estaría mal formado porque no coincide con la sintaxis.
Editar
Clang permite = 0x0
, = 0b0
y = 00
(31.12.2013). Eso es incorrecto y debería arreglarse en el compilador, por supuesto.
= 0
tiene un significado fijo allí. No es realmente un número cero allí. Por lo tanto, no puedes simplemente reemplazarlo así.