¿Cuándo / por qué querría eliminar explícitamente mi constructor? Suponiendo que la razón es evitar su uso, ¿por qué no hacerlo private?
class Foo
{
public:
Foo() = delete;
};
¿Cuándo / por qué querría eliminar explícitamente mi constructor? Suponiendo que la razón es evitar su uso, ¿por qué no hacerlo private?
class Foo
{
public:
Foo() = delete;
};
delete. Tanto la pregunta como la respuesta de Luchian fácilmente se califican como constructivas. Cualquiera que no respire los puntos más finos de C ++ 11, pero lo necesitará pronto, obtendrá algo de ambos.
Respuestas:
Qué tal si:
//deleted constructor
class Foo
{
public:
Foo() = delete;
public:
static void foo();
};
void Foo::foo()
{
Foo f; //illegal
}
versus
//private constructor
class Foo
{
private:
Foo() {}
public:
static void foo();
};
void Foo::foo()
{
Foo f; //legal
}
Básicamente son cosas diferentes. privatele dice que solo los miembros de la clase pueden llamar a ese método o acceder a esa variable (o amigos, por supuesto). En este caso, es legal que un staticmétodo de esa clase (o cualquier otro miembro) llame a un privateconstructor de una clase. Esto no es válido para constructores eliminados.
Muestra aquí .
¿Por qué eliminar explícitamente el constructor?
Otra razón:
usodelete cuando quiero asegurarme de que se llame a una clase con un inicializador. Lo considero una forma muy elegante de lograr esto sin verificaciones de tiempo de ejecución.
El compilador de C ++ realiza esta comprobación por usted.
class Foo
{
public:
Foo() = delete;
Foo(int bar) : m_bar(bar) {};
private:
int m_bar;
}
Este código, muy simplificado , asegura que no hay instanciación como esta:Foo foo;
Footuviera numerosos constructores, pero no uno predeterminado, Foo foo;provocaría un error mucho más largo que enumera todos los constructores privados, protegidos y definidos implícitamente que no pudo hacer coincidir.
Me he encontrado con ctors predeterminados declarados como 'eliminados' en el código fuente de LLVM (en AlignOf.h, por ejemplo). Las plantillas de clases asociadas suelen estar en un espacio de nombres especial llamado 'llvm :: detail'. Creo que todo el propósito allí era que consideraran esa clase solo como una clase de ayuda. Nunca tuvieron la intención de instanciarlos; solo para usarlos dentro del contexto de otras plantillas de clase con algunos trucos de metaprogramación que se ejecutan en tiempo de compilación.
P.ej. existe esta plantilla de clase AlignmentCalcImpl que se usa solo dentro de otra plantilla de clase llamada AlignOf como parámetro para el operador sizeof (.). Esa expresión se puede evaluar en tiempo de compilación; y no hay necesidad de crear una instancia de la plantilla -> entonces, ¿por qué no declarar la eliminación predeterminada de ctor para expresar esta intención?
Pero es solo mi suposición.
= default, ni siquiera la clase puede usarlo, y personalmente prefiero ver Uso de la función eliminada. over La función es privada. El primero establece explícitamente "Esto no está destinado a ser utilizado". Si algo sale de eso, la clase que no pueda usarlo realmente hace una diferencia semántica.