2009-07-17 8 views
13

Entonces, tengo una clase. Es una clase útil. Me gusta mucho. Vamos a llamarlo MyUsefulClass. MyUsefulClass tiene un método público. Vamos a llamarlo processUsefulData(std::vector<int>&).¿deberían las "funciones auxiliares" de la clase C++ ser miembros, libres o libres de espacio de nombres?

Ahora supongamos processUsefulData realmente tiene dos cosas y quiero refactorearlo de esto:

std::vector<int> MyUsefulClass::processUsefulData(std::vector<int>& data) 
{ 
    for (/*...*/) 
    { 
     for (/*...*/) 
     { 
      // a bunch of statements... 
     } 
    } 

    for (/*...*/) 
    { 
     for (/*...*/) 
     { 
      // a bunch of other statements... 
     } 
    } 
    return data; 
} 

Ahora, quiero dividir estas responsabilidades y volver a escribir el código como

std::vector<int> MyUsefulClass::processUsefulData(std::vector<int>& data) 
{ 
    doProcessA(data, dataMember_); 
    doProcessB(data, otherDataMember_); 
    return data; 
} 

Por lo tanto, No sé si debería hacer que las dos funciones auxiliares liberen funciones o funciones miembro, y cuando cada una sea apropiada. Tampoco sé si es mejor hacerlos en un espacio de nombre anónimo o no. ¿Alguien sabe buenos tiempos para hacer esto?

+0

Generalizar de esta manera no le dará una buena respuesta. Cada situación depende de lo que estás haciendo. –

Respuesta

7

función libre/

les haría funciones libres es posible (que no necesitan el acceso a las partes internas de la clase).Si trabajan en un conjunto de atributos o necesitan acceso a otros miembros, conviértanlo en una función miembro.

acceso

Si el código sólo tiene sentido en este ámbito, y no será utilizada de otro tipo de código a continuación, hacer que privada: privada si es un miembro, o puesto en práctica en un espacio de nombres sin nombre si es una función gratuita.

Si otro código se beneficiará al usar el código, publíquelo en la interfaz. Eso significa protegerlo si es miembro o si se tiene acceso a la función gratuita a través de un encabezado en un espacio de nombre nombrado (o espacio de nombre global).

3

Generalmente las hago funciones de miembros protected o private. Dependerá de si planea derivar la clase y anular las funciones.

Si son funciones suficientemente comunes que se usan en otras clases, muévalas a funciones estáticas contenidas en una clase común o en un objeto separado que use su clase.

0

Piensa en el alcance. ¿Se usarán esas funciones en otra clase o en otro lugar? ¿Deberían ser públicamente convocables?

Parece que deberían ser funciones de miembro privado para mí, pero todo depende de la estructura general de su alcance.

2

Siempre prefiera las funciones gratuitas que las de miembros. Ver mi respuesta here para saber por qué.

+0

En realidad, su otra respuesta no contiene una explicación directamente ;-) – Simson

+2

@Simson - Curiosamente, se refiere al lector a [esta publicación del blog] (http://www.gotw.ca/publications/mill08.htm), que luego remite al lector a [esta publicación previa] (http://www.gotw.ca/publications/mill02.htm). Afortunadamente para nuestra cordura, esa publicación no nos remite a esta publicación SO (aunque se refiere a la primera publicación del blog). –

0

Funciones de miembro ciertamente si la función original tenía sentido como función de miembro.

Privado/protegido Mi humilde opinión depende de cómo se usa su funcionalidad: si todavía se requiere el funcionamiento de la función original y el refactor es únicamente para hacer el código más limpio, entonces protegerlos o privados y llamarlos desde la función normal. Obtienes el refactor pero mantienes la interfaz pública de la clase intacta de esa manera.

2

El hecho de que menciones funciones gratuitas me lleva a pensar que el "montón de otras declaraciones" no requiere acceso a los datos de clase. Si es así, hazlos gratis. Esto reduce la complejidad de su encabezado de clase, además de que las funciones gratuitas son más fáciles de usar en los algoritmos estándar (tal vez std :: for_each ya que de todos modos está trabajando con vectores).

10

Por lo general, las rutinas de ayuda rutinas "libres" en un espacio de nombres anónimo siempre que sea posible. De esta forma, no complico la interfaz (desactivada en el archivo * .h) con cosas de las que los clientes no tienen que preocuparse.

Sin embargo, debe tener cuidado de no introducir la no reentrada haciendo eso. Por ejemplo, modificando objetos de datos globales o locales estáticos en lugar de miembros de la clase. Si necesita hacer eso, es mejor que sea un miembro adecuado de la clase. función miembro

+0

+1 ¡Buen punto para mantener limpia la interfaz! – math

Cuestiones relacionadas