2010-04-18 11 views
11

yo que sea breve y simplemente le mostrará un ejemplo de código:más corta y la mejor manera de ejemplo, "Fecha"/limpia una clase

class myClass 
{ 
public: 
    myClass(); 
    int a; 
    int b; 
    int c; 
} 

// In the myClass.cpp or whatever 
myClass::myClass() 
{ 
a = 0; 
b = 0; 
c = 0; 
} 

bien. Si sé que tengo una instancia de myClass y establezco algo de basura al azar en a, byc.

  • ¿Cuál es la mejor manera de restablecerlos todos al estado después de que se llamó al constructor de la clase, así que: 0, 0 y 0?

me ocurrió de esta manera:

myClass emptyInstance; 
myUsedInstance = emptyInstance; // Ewww.. code smell? 

O ..

myUsedInstance.a = 0; myUsedInstance.c = 0; myUsedInstance.c = 0; 
  • creo que usted sabe lo que quiero, ¿hay alguna manera mejor para lograr esto?

Respuesta

16
myUsedInstance = myClass(); 

C++ 11 es muy eficiente si se utiliza este formulario; el operador de asignación de movimiento se encargará de limpiar manualmente cada miembro.

+0

Ahora, ¿y si quiero hacer esto desde adentro? '* this = MyClass()'? – Xeverous

3

Simplemente asigne una clase construida por defecto, como la que tiene. Solo use un temporal, sin embargo:

struct foo 
{ 
    int a, b, c; 

    foo() : 
    a(), b(), c() 
    {} // use initializer lists 
}; 

foo f; 
f.a = f.b =f.c = 1; 

f = foo(); // reset 
+0

Probablemente sea una buena manera pero me confunde mucho. – Oper

+1

@Oper Es la forma estándar de C++ de hacer lo que usted pidió: cualquier programador de C++ razonablemente experimentado reconocerá el meme. –

-1

Es posible que desee considerar el uso de la colocación nueva. Esto le permitirá usar la misma memoria pero llamar de nuevo al constructor.

No olvides llamar al destructor antes de usar la ubicación nueva, sin embargo.

+5

En otras palabras, es posible que no desee considerar esto. Solo lo haría en circunstancias muy excepcionales, y aun así lo pensaría dos veces: a = A() casi siempre es la mejor opción. –

6

Puede implementar clear como una función genérica para cualquier tipo intercambiable. (Un tipo que se puede intercambiar es común y se realiza implícitamente en C++ 0x con un constructor de movimiento. Si tiene un constructor de copias y un operador de asignación que se comportan de manera adecuada, su tipo se puede cambiar automáticamente en C++ actual. Puede customize swapping para sus tipos fácilmente , también.)

template<class C> 
C& clear(C& container) { 
    C empty; 
    using std::swap; 
    swap(empty, container); 
    return container; 
} 

Esto requiere el menor trabajo de usted, a pesar de que puede parecer un poco más complicado, ya que sólo tiene que hacer una vez y luego trabaja en casi todas partes. Utiliza la expresión vacía-swap para tener en cuenta las clases (como std :: vector) que no borran todo en la asignación.


Si usted ha visto que el canje es un cuello de botella (que sería raro), se especializan él (sin tener que cambiar todo uso de clara !) en la cabecera myClass 's:

template<> 
myClass& clear<myClass>(myClass& container) { 
    container = myClass(); 
    return container; 
} 

If myClass es una plantilla, no se puede especializar en parte clara, pero se puede sobrecargar (de nuevo en la cabecera de la clase):

template<class T> 
myClass<T>& clear(myClass<T>& container) { 
    container = myClass<T>(); 
    return container; 
} 

La razón para definir tal especialización o sobrecarga en El encabezado de myClass es para que sea fácil evitar la violación de la ODR al tenerlos disponibles en un solo lugar y no en otro. (Es decir, están siempre disponibles si myClass está disponible.)

+2

Gran respuesta. :) – GManNickG

+0

Es posible que desee enfatizar por qué sugiere esto, en lugar de simplemente confiar en el constructor predeterminado como otros sugirieron. –

+0

@Dennis: ¿Cómo es esta versión? –

Cuestiones relacionadas