c++ - Función libre versus función miembro
dependencies member-functions (3)
¿Cuál es la ventaja de tener una función libre (en el espacio de nombres anónimo y accesible solo en un único archivo fuente) y enviar todas las variables como parámetros en lugar de tener una función de miembro de clase privada libre de cualquier parámetro y acceder directamente a las variables de miembro? ¡Gracias!
encabezamiento:
Class A {
int myVariable;
void DoSomething() {
myVariable = 1;
}
};
fuente:
namespace {
void DoSomething2(int &a) {
a = 1;
}
}
int A::SomeFunction() {
DoSomething2(myVariable); // calling free function
DoSomething(); // calling member fucntion
}
Si prefiere convertirlos en miembros, entonces ¿qué pasa si tengo un caso en el que primero llamo a una función que no está accediendo a ninguna variable de miembro pero esa función llama a otra función que está accediendo a un miembro? ¿Deberían ser ambas funciones miembros o libres?
La principal ventaja de las funciones libres frente a las funciones miembro es que ayuda a desacoplar la interfaz de la implementación. Por ejemplo, std::sort
no necesita saber nada sobre el contenedor subyacente en el que opera, solo que se le da acceso a un contenedor (a través de iteradores) que proporciona ciertas características.
En su ejemplo, el método DoSomething2
no hace mucho para disminuir el acoplamiento, ya que todavía tiene que acceder al miembro privado al pasarlo por referencia. Es casi seguro que es más obvio simplemente hacer la mutación de estado en el método DoSomething
simple.
Cuando puede implementar una tarea o un algoritmo en términos de la interfaz pública de una clase, eso lo convierte en un buen candidato para realizar una función gratuita. Scott Meyers resume un conjunto razonable de reglas aquí: http://cpptips.com/nmemfunc_encap
Una de las ventajas de una función que no es miembro en un archivo de origen es similar a las ventajas del lenguaje Pimpl : los clientes que usan sus encabezados no tienen que volver a compilar si cambia su implementación.
// widget.h
class Widget
{
public:
void meh();
private:
int bla_;
};
// widget.cpp
namespace {
void helper(Widget* w) // clients will never know about this
{ /* yadayada */ }
}
void widget::meh()
{ helper(this); }
Por supuesto, cuando se escribe así, helper()
solo puede usar la interfaz pública de Widget
, por lo que ganas poco. Puedes poner una declaración de friend
para helper()
en Widget
pero en algún momento es mejor que cambies a una solución Pimpl en toda regla.
vea esta pregunta: Elemento efectivo de C ++ 23 Prefiera las funciones que no sean miembros no amigables a las funciones miembro y también las Funciones miembro C ++ vs Funciones gratuitas
Debe preferir las funciones libres, en la medida en que promueva el acoplamiento suelto.
Considere convertirla en una función miembro solo si funciona en las entrañas de su clase , y considera que realmente está ligada a su clase.
Es un punto de los estándares de codificación del libro 101 C ++ , que establece que prefieren la función libre y la función estática a las funciones miembro.
A pesar de que esto se puede considerar basado en la opinión, permite mantener poca clase y separar las preocupaciones.
Esta answer dice: "el motivo de esta regla es que al usar las funciones de los miembros puede confiar demasiado en los aspectos internos de una clase por accidente".