virtuales puro protegidos polimorfismo herencia funciones clase atributos abstracta c++ c++11 virtual pure-virtual nullptr

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í.