2008-12-09 14 views
9

Todas las variables miembro y las funciones miembro en mi clase ClassA son estáticas.Impedir la creación de una clase cuyas funciones miembro sean todas estáticas

Si un usuario intenta (por error) crear un objeto de esta clase, recibe una advertencia: "ClassA, variable local nunca referenciada", porque todas las funciones son estáticas, por lo que nunca se hace referencia a este objeto. Por lo tanto, quiero evitar que el usuario intente crear un objeto de esta clase.

¿Sería suficiente crear un constructor privado predeterminado (sin variables)? ¿O también tengo que crear un constructor de copia privada y un operador de asignación privada (para evitar el uso de los constructores por defecto)? Y si tengo que crearlos también, tal vez sería mejor crear una función virtual pura y falsa, ¿y esto evitará que el usuario cree un objeto?

Gracias

+0

¡Es C++, no Java! ¿Por qué necesita crear una clase para mantener las funciones estáticas? solo haga que sean globales, o debajo de un espacio de nombres {} en lugar de una clase – hasen

+2

, porque si usa un espacio de nombres en su lugar, no puede tener miembros privados estáticos para mantener el estado privado. –

+0

¡Claro que puedes! hacerlos estáticos y no estarán disponibles fuera de esa unidad de compilación. – Ferruccio

Respuesta

10

Como dijeron otros, un espacio de nombres es lo que debe usar. Si usted desea permanecer con su clase, cree una clase que tiene un constructor privado, y derivar de ella, para que su intención obvia:

class NonConstructible { 
    NonConstructible(); 
}; 

class SuperUtils: NonConstructible { 
    static void foo(); 
    // ... 
    static std::vector<int> globalIDs; 
    // ... 
}; 

Ok, ahora vamos a ver en el espacio de nombres que son el única manera de hacer esto:

namespace SuperUtils { 
    void foo() { 
     // .... 
    } 

    std::vector<int> globalIDs; 
}; 

usted puede llamar a que el uso de SuperUtils::foo(); en ambos casos, pero el espacio de nombres tiene la ventaja de que en un ámbito que puede utilizar la declaración de espacio de nombres y la directiva para traer ciertos o todos los miembros en el alcance actual, para que pueda hacer referencia a em sin utilizar SuperUtils:::

void superFunction() { 
    using namespace SuperUtils; 
    foo(); 
} 

Si bien en general, que debe evitarse, puede ser útil cuando el método se usa exclusivamente la cantidad de cosas de SuperUtils, que pueden mejorar la legibilidad del código.

+0

Pero ahora ha hecho que los ID globales sean efectivamente públicos, cuando anteriormente era privado. Si los globales deben existir, ¿cómo es una mejora para ellos ser accesibles desde cualquier lugar? –

+0

Para obtener lo mejor de ambos, puede poner los globales en una clase, y luego tener funciones de amigo no miembro para acceder a ellos. O coloque los elementos globales y las funciones en la clase, luego tenga funciones libres en línea en un espacio de nombres para llamarlos sin especificar el alcance de la clase. –

+0

"anteriormente era privado" - lo siento, quiero decir que anteriormente podría ser privado. Interlocutor no dijo que era. –

11

Crear un constructor predeterminado privado debería ser suficiente. Las otras dos construcciones predeterminadas (constructor de copia y asignación) dependen de que una instancia funcione correctamente. Si no hay un constructor predeterminado, entonces no hay forma de crear una instancia, por lo tanto, no hay forma de llegar realmente a la parte de construcción de la copia.

Es probable que le ahorre algunos dolores de cabeza aunque para definir los 3 como privados y no implementados.

+0

Una vez más, votamos porque ... – JaredPar

+2

Debería ser: declarar pero no definir (implementar) el constructor. Eso se ocupará tanto del código externo que intenta crear una instancia (el constructor es privado) como del código interno que crea erróneamente un objeto: error de enlazador como constructor no definido. –

3

Para utilizar un constructor de copia, debe tener un objeto para copiar, por lo que si ha bloqueado el constructor predeterminado, debe estar seguro.

20

En lugar de utilizar una clase con todos los métodos estáticos, puede que sea mejor hacer que los métodos funcionen independientemente en un espacio de nombres separado. La sintaxis de llamada sería la misma:

namespace::function() en lugar de classname::function()

y no tenga que tratar con alguien que intenta crear una instancia de la clase.

+0

Definitivamente mucho mejor que tener una clase con todos los métodos estáticos. – Naveen

+1

Estoy totalmente en desacuerdo. Puedo escribir 'using namespace Xxxx;' y luego no tendré que escribir 'Xxxx :: Symbol' - solo 'Symbol' es suficiente. El enfoque de clase estática obliga al programador a escribir 'Clase :: Símbolo' cada vez. – xxbbcc

0

La mejor manera de evitar la creación de objetos que no sean de pila es hacer que destructor sea privado. Entonces no hay forma de que el compilador pueda destruir el objeto cuando se sale del alcance y se quejará. Sin embargo, esto no evitará que nadie haga novedades.

Cuestiones relacionadas