2011-08-29 12 views
8

Estaba viendo las nuevas funciones de C++ 11 y una de ellas me confunde, porque no puedo encontrar la manera de usarla en Real World.Funciones eliminadas y predeterminadas Ejemplos de Real World

Son funciones eliminadas y incumplidas, ¿Alguien tiene ejemplos del uso del mundo real o es solo una de esas características que simplemente agrega algo de azúcar?

Respuesta

8
struct A 
{ 
    A(const A& arg) : data(arg.data) 
    { 
    do_something_special(); 
    } 

    // by writing copy constructor, we suppress the generation of 
    // implicit default constructor A::A() 

    int data; 
}; 

void foo1() 
{ 
    A a; // does not work, since there's no default constructor 
} 

Digamos que nuestro constructor por defecto no hace nada especial y es (más o menos) igual al compilador generó uno. Podemos solucionarlo, ya sea escribiendo nuestro propio constructor por defecto (que puede resultar tedioso si nuestra clase tiene muchos miembros no estáticos), o mediante el uso de la sintaxis = default:

struct A 
{ 
    A() = default; 
    A(const A& arg) : data(arg.data) 
    { 
    do_something_special(); 
    } 

    int data; 
}; 

Eliminación de funciones es útil cuando quiero prohibir el uso de sobrecargas específicas o especializaciones de plantillas, o simplemente prohibir copiar (o mover) objetos.

void foo(char c) {} 
void foo(int i) = delete; // do not allow implicit int -> char conversion 

Cuando se quiere prohibir la copia (es decir, objetos de hilo), la forma idiomática habitual es declarar constructor de copia privada sin aplicación (sí, o impulsar el uso :: noncopyable). Si bien esto funciona en la mayoría de los casos, a veces puede entrar en algunos errores oscuros del enlazador. Consideremos:

struct A 
{ 
    A() = default; 

    friend void foo(); 

private: 
    A(const A&); 
}; 

void foo() 
{ 
    A a; 
    A b(a); // results in linker error in gcc 
} 

Haciendo A(const A&) borrar, le evitan posibles errores de enlace y crea nuestra intención (no permitir la copia) muy claro.

9

Una función de miembro especial declarada por el usuario no es trivial. Si una clase tiene funciones miembro no triviales especiales, la clase no es POD. Por lo tanto, este tipo es POD:

struct S { 
    S() = default; 
    S(int) { } 
}; 

pero este tipo no es POD:

struct S { 
    S() { } 
    S(int) { } 
}; 
+0

@Christian: Si simplemente teníamos 'struct S {S (int) {}}; ', la presencia de' S (int) 'haría suprimir el constructor predeterminado declarado implícitamente. –

+0

Las reglas para POD se han relajado en C++ 0x/11, por lo que su segundo ejemplo también sería un POD en C++ 0x/11. También puede usar los nuevos rasgos :: is_pod para verificarse con una afirmación estática, por ejemplo. – David

+0

@David: Las reglas para POD han sido relajadas, pero el segundo 'S' todavía no es POD. Una estructura POD debe ser una clase trivial. Una clase trivial debe tener un constructor predeterminado trivial. Un constructor predeterminado proporcionado por el usuario no es trivial. El segundo 'S' tiene un constructor predeterminado proporcionado por el usuario y, por lo tanto, no es POD. –

1

Utilizaría las funciones eliminadas para las clases en las que desea evitar la copia o la creación de instancias directas, por ejemplo (a la singleton en la que desea realizar una función get_instance()). También puedes utilizar eliminar para evitar ciertas variaciones de tu constructor.

El valor predeterminado es útil si desea que el compilador genere el constructor para cualquiera de los generados implícitamente. Por ejemplo, si crea un constructor de argumento personalizado, el compilador no generaría el argumento predeterminado no, por lo que podría solicitar que se genere para usted con la palabra clave predeterminada.

Vea aquí ejemplos de lo anterior

http://www2.research.att.com/~bs/C++0xFAQ.html#default

Cuestiones relacionadas