2011-02-07 28 views
10

duplicados posibles:
Where would you use a friend function vs a static function?
C++: static member functionsCuándo usar la función de miembro estático?

Cuando es apropiado utilizar una función miembro estático en C++? Por favor, dame un ejemplo del mundo real.

+2

¿Qué pasa con la etiqueta 'oops'? – Maxpm

+2

Edité la pregunta porque creo que el autor solo quiere decir "OOP" u Programación Orientada a Objetos. –

+1

http://stackoverflow.com/questions/4723143/c-static-member-functions – Mahesh

Respuesta

11

buenos usos de los métodos estáticos:

  • Meta-programación. El ejemplo del mundo real es la plantilla std :: char_traits. Todas las funciones miembro son estáticas
  • Hacer que sea una función miembro estática le da acceso a miembros privados de la clase, aunque un amigo sería suficiente aquí también
  • Por lo tanto, una función miembro estática protegida solo está accesible a la clase y clases derivadas de eso.

Tenga en cuenta que el último caso se aplica a una función miembro estática protegida pero no a una privada. En el último caso, simplemente lo pondría en la unidad de compilación de la clase, ocultándolo como un detalle de implementación. Para uno protegido, aunque desea que sea visible, aunque de forma restringida.

Un caso típico de eso es "engañar" la falta de herencia de la amistad.

class B 
{ 
    friend class A; 
    // lots of private stuff 
}; 

class A 
{ 
protected: 
    static void callsSomePrivateMembers(B& b); 
}; 

class AChild : public A 
{ 
    void foo(B& b); 
} 

void AChild::foo(B& b) 
{ 
     // AChild does not have private access to B as friendship is not inherited 
     // but I do have access to protected members of A including the static ones 

    callsSomePrivateMembers(b); // get to call them through a back-door 
} 
+0

+ 1 para la metaprogramación, pero no obtengo la "función miembro que necesita acceso privado". ¿No es esto lo que hace la función de miembro regular? – Simone

+0

Quise decir que al convertirlo en una función miembro estática le da acceso a áreas privadas de la clase. – CashCow

4

Un ejemplo común que encontrará (en un ejemplo del mundo real) es cuando está creando un hilo. Las API comunes de subprocesos (POSIX/pthreads, Boost y Win32 CreateThread) requieren una firma específica. La única forma de obtener esa firma en una función miembro es haciendo que la función sea estática.

+0

Una función libre funcionaría tan bien. –

+0

@ Matthieu: En algunos casos, sí. Sin embargo, si está creando una clase de derivador de subprocesos, ese no será el caso. –

+0

No entiendo por qué, ¿podría dar un ejemplo de código? (lo siento ...: /) –

2

He leído mal su pregunta y respondido cuando es apropiado usar funciones estáticas.

Se refiere a las funciones estáticas de los miembros. he aquí un ejemplo de cuándo utilizar una función miembro estática - para envolver una llamada rosca dentro de una clase, de manera que el hilo tiene acceso a su clase ...:

static unsigned WINAPI ArchiveAgent::LogMsgPump(PVOID pData) 
{ 
    ArchiveAgent* pSmith = reinterpret_cast<ArchiveAgent*>(pData); 

    if(pSmith) 
     pSmith->LogMsgPump(); 
    else 
     return -1; 

    return 0; 
} 

unsigned WINAPI ArchiveAgent::LogMsgPump() 
{ 
    CoInitializeEx(NULL, COINIT_MULTITHREADED); 

    // .... 

    CoUninitialize(); 
    return 0; 
} 

Aquí fue mi respuesta para funciones estáticas llanura de edad .. Uso funciones estáticas donde no tiene sentido que esa función pertenezca a una clase.

Generalmente tiendo a agregar estas funciones a un espacio de nombres personalizado. El siguiente ejemplo de función estática es parte de un espacio de nombres que llamo shellutils:

static HRESULT CreateFolder(CString & sPath) 
{ 
// create the destination folder if it doesn't already exist 

HRESULT hr  = S_OK; 
DWORD dwError = 0; 

if(sPath.GetLength() == 0 || sPath.GetLength() < 2)     
    return E_UNEXPECTED; 

if(GetFileAttributes((LPCWSTR) sPath) == INVALID_FILE_ATTRIBUTES) 
{   
    dwError = SHCreateDirectoryEx(NULL, (LPCWSTR)sPath, NULL); 

    if (dwError != ERROR_SUCCESS && dwError != ERROR_FILE_EXISTS && dwError != ERROR_ALREADY_EXISTS) 
     hr = HRESULT_FROM_WIN32(dwError); 
} 

return hr; 

}

+0

-1: pregunta por las funciones estáticas de los miembros. No funciones estáticas en general. –

+0

se perdió eso, revisará la respuesta! –

+0

¡No creo que haya valido la pena señalarme! –

3

Es posible que desee utilizar la función sin un objeto instanciado. Además, si la función se llama desde otra función estática, debe ser estática.

+0

¿Por qué es eso (segundo punto)? Admitiré que no trabajo en C++, por lo que podría estar perdiendo sus complejidades, pero al menos tanto en C# como en Java, las funciones estáticas pueden usar miembros de instancia muy bien, todo lo que se necesita es tener una instancia del tipo . ¿Es C++ diferente a este respecto? –

+0

"Puede usar la función sin un objeto instanciado" - ¡parece ser la única respuesta que realmente responde a la pregunta! –

2

Busque un patrón de diseño llamado singleton. En resumen, es una forma de restringir la creación de objetos. Por lo tanto, la única forma de crear un objeto es llamar a una función miembro de C++ que sea estática.

2

Un ejemplo típico puede ser una clase singleton donde el método GetInstance() estático devuelve la instancia singleton de la clase.

class Singleton 
{ 
    static Singleton instance; 

    private Singleton() 
    { 
    } 

    static Singleton & GetInstance() 
    { 
     if(instance == null) 
     instance = new Singleton(); 

     return instance; 
    } 
} 
+1

Es mejor usar una instancia estática de nivel de función de la clase para lograr el patrón Singleton. Ver "Meyers Singleton" (http://www.devarticles.com/c/a/Cplusplus/C-plus-plus-In-Theory-The-Singleton-Pattern-Part-I/4/) –

+0

Me gustaría añadir ... El uso de un singleton es aconsejable solo después de conocer los pros y los contras que ofrece ... Aparte de algunos escenarios excepcionales, los Singleton suelen terminar creando más problemas ... Piensa ... Problemas de transmisión ... destrucción de singleton ... –

6

El lugar natural para utilizarlo es cuando no se puede utilizar una función gratuita porque es necesario acceder a la parte interna de la clase. El ejemplo más típico de esto es una función de constructor como la siguiente. El constructor de Foo es privado para asegurarse de que no se construye de ninguna otra forma que no sea con la función de constructor.

#include <iostream> 

class Foo { 
public: 
    static Foo* createFoo() {return new Foo();} 
private: 
    Foo() {} 
}; 

int main() { 
    //Foo nonBuiltFoo; //wont compile 
    Foo* freshFoo = Foo::createFoo(); 
    delete freshFoo; 
    return 0; 
} 

Un uso típico de eso es el patrón Singleton mencionado anteriormente. Cuando no tiene que acceder a partes privadas y protegidas de la clase, no es necesario tener funciones miembro estáticas (se pueden usar funciones gratuitas), pero hay algunas que también usan funciones de miembros estáticos cuando están dentro del dominio de la clase pero no restringido/lógico para usar la función en una sola instancia.

Cuestiones relacionadas