class my_class
{
...
my_class(my_class const &) = delete;
...
};
¿Qué = delete
significa en ese contexto?
¿Hay otros "modificadores" (que no sean = 0
y = delete
)?
c++
function
c++11
declaration
delete-operator
Pat O'Keefe
fuente
fuente
#define
a la Qt que se evaluaba a 0 y luego declaraba una función oculta o algo así.Respuestas:
Eliminar una función es una característica de C ++ 11 :
fuente
=delete
hace que el método sea inaccesible incluso desde contextos que pueden verprivate
métodos (es decir, dentro de la clase y sus amigos). Esto elimina cualquier incertidumbre cuando estás leyendo el código. @Prasoon, ese segundo ejemplo todavía solo está eliminando constructores; sería bueno ver un eliminado,operator long ()
por ejemplo.= delete
es mejor que usarprivate
u otros mecanismos similares porque generalmente desea que la función prohibida se declare visiblemente y se considere para la resolución de sobrecarga, etc., de modo que pueda fallar lo antes posible y proporcionar el error más claro al usuario. Cualquier solución que implique "ocultar" la declaración reduce este efecto.= 0
significa que una función es puramente virtual y no puede crear una instancia de un objeto de esta clase. Necesitas derivar de él e implementar este método= delete
significa que el compilador no generará esos constructores para usted. AFAIK esto solo está permitido en el constructor de copia y el operador de asignación. Pero no soy demasiado bueno en el próximo estándar.fuente
=delete
sintaxis. Por ejemplo, puede usarlo para rechazar explícitamente algún tipo de conversiones implícitas que puedan tener lugar con la llamada. Para esto, simplemente elimine las funciones sobrecargadas. Echa un vistazo a la página de Wikipedia en C ++ 0x para obtener más información.= delete
no es del todo correcta.= delete
se puede usar para cualquier función, en cuyo caso se marca explícitamente como eliminado y cualquier uso da como resultado un error del compilador. Para funciones especiales de miembros, esto también significa en particular que el compilador no las genera para usted, pero eso es solo el resultado de ser eliminado y no lo que= delete
realmente es.Este extracto del lenguaje de programación C ++ [4ª edición] - El libro de Bjarne Stroustrup habla sobre el verdadero propósito de usar
=delete
:fuente
Como parece que nadie más respondió a esta pregunta, debo mencionar que también la hay
=default
.https://docs.microsoft.com/en-us/cpp/cpp/explicitly-defaulted-and-deleted-functions#explicitly-defaulted-functions
fuente
Los estándares de codificación con los que he trabajado han tenido lo siguiente para la mayoría de las declaraciones de clase.
Si usa cualquiera de estos 6, simplemente comente la línea correspondiente.
Ejemplo: la clase FizzBus solo requiere dtor y, por lo tanto, no usa los otros 5.
Comentamos solo 1 aquí e instalamos la implementación de él en otro lugar (probablemente donde lo sugiere el estándar de codificación). Los otros 5 (de 6) no están permitidos con eliminar.
También puede usar '= eliminar' para no permitir promociones implícitas de valores de diferentes tamaños ... ejemplo
fuente
= delete
es una característica introducida en C ++ 11. Según=delete
no se permitirá llamar a esa función.En detalle.
Supongamos en una clase.
Al llamar a esta función para la asignación de obj, no se permitirá. El operador de asignación de medios va a restringir la copia de un objeto a otro.
fuente
Nuevo estándar C ++ 0x. Consulte la sección 8.4.3 en el borrador de trabajo de N3242
fuente
Una función eliminada está implícitamente en línea
(Anexo a las respuestas existentes)
... Y una función eliminada será la primera declaración de la función (excepto para eliminar especializaciones explícitas de plantillas de funciones; la eliminación debe realizarse en la primera declaración de la especialización), lo que significa que no puede declarar una función y luego eliminarla, por ejemplo, en su definición local a una unidad de traducción.
Citando [dcl.fct.def.delete] / 4 :
Se puede especializar una plantilla de función primaria con una definición eliminada
Aunque una regla general es evitar las plantillas de funciones especializadas ya que las especializaciones no participan en el primer paso de la resolución de sobrecarga, existen algunos contextos discutibles en los que puede ser útil. Por ejemplo, cuando se utiliza una plantilla de función primaria no sobrecargada sin definición para que coincida con todos los tipos que a uno no le gustaría convertir implícitamente en una sobrecarga de coincidencia por conversión; es decir, eliminar implícitamente varias coincidencias de conversión implícita implementando solo coincidencias de tipo exacto en la especialización explícita de la plantilla de función primaria no definida y no sobrecargada.
Antes del concepto de función eliminado de C ++ 11, uno podía hacer esto simplemente omitiendo la definición de la plantilla de función primaria, pero esto daba oscuros errores de referencia indefinidos que posiblemente no dieron ninguna intención semántica del autor de la plantilla de función primaria (omitido intencionalmente ?) Si, en cambio, eliminamos explícitamente la plantilla de función primaria, los mensajes de error en caso de que no se encuentre una especialización explícita adecuada se vuelven mucho más agradables, y también muestran que la omisión / eliminación de la definición de la plantilla de función primaria fue intencional.
Sin embargo, en lugar de simplemente omitir una definición para la plantilla de función primaria anterior, arrojando un oscuro error de referencia indefinido cuando no hay coincidencias de especialización explícitas, la definición de plantilla primaria se puede eliminar:
Produciendo un mensaje de error más legible, donde la intención de eliminación también es claramente visible (donde un error de referencia indefinido podría hacer que el desarrollador piense que es un error irreflexivo).
Volviendo a por qué querríamos usar esta técnica. Una vez más, especializaciones explícitas podrían ser útiles para implícitamente eliminar las conversiones implícitas.
fuente
Esto es algo nuevo en los estándares C ++ 0x donde puede eliminar una función heredada.
fuente
void foo(int); template <class T> void foo(T) = delete;
detiene todas las conversiones implícitas. Soloint
se aceptan argumentos de tipo, todos los demás intentarán instanciar una función "eliminada".