resueltos relaciones programacion poo orientada objetos metodos herencia entre ejercicios codigo clases c++ class private private-members private-methods

relaciones - ¿Hay algún uso para que una clase contenga solo(de manera predeterminada) miembros privados en c++?



programacion orientada a objetos (6)

Los miembros de una clase son por defecto privados en c ++.

Por lo tanto, me pregunto si existe algún uso posible para crear una clase que tenga todos sus miembros (variables y funciones) establecidos de forma predeterminada en privado.

En otras palabras, ¿existe alguna definición de clase significativa sin ninguna de las palabras clave public , protected o private ?


¿Adquisición de recursos de aplicación amplia?

#include <iostream> class C { C() { std::cout << "Acquire resource" << std::endl; } ~C() { std::cout << "Release resource" << std::endl; } static C c; }; C C::c; int main() { return 0; }

Como se indica en los comentarios a continuación, tengo una aplicación industrial que tuvo que "bloquear" algún dispositivo de hardware mientras se ejecutaba el programa. Pero es probable que uno encuentre otro uso para esto, ya que, después de todo, es solo un caso "degenerado" o RAII .

En cuanto al uso de métodos "privados" fuera del bloque de declaración: uso un miembro estático aquí. Por lo tanto, se declara en un punto donde los miembros privados son accesibles . No estás limitado a constructor / destructor. Incluso puede (ab) usar métodos estáticos y luego invocar métodos de instancia privados usando una interfaz fluida :

class C { C() { std::cout << "Ctor " << this << std::endl; } ~C() { std::cout << "Dtor" << this << std::endl; } static C* init(const char* mode) { static C theC; std::cout << "Init " << mode << std::endl; return &theC; } C* doThis() { std::cout << "doThis " << std::endl; return this; } C* doThat() { std::cout << "doThat " << std::endl; return this; } static C *c; }; C *C::c = C::init("XYZ") ->doThis() ->doThat(); int main() { std::cout << "Running " << std::endl; return 0; }

Ese código sigue siendo válido (ya que todos los miembros de C son accesibles en el punto de declaración de C::c ). Y producirá algo así:

Ctor 0x601430 Init XYZ doThis doThat Running Dtor0x601430


¿Significativo? ¿Buena práctica? Probablemente no, pero aquí va:

class DataContainer { friend class DataUser; int someDataYouShouldNotWorryAbout; }; class DataUser { public: DataUser() { container.someDataYouShouldNotWorryAbout = 42; } private: DataContainer container; };


Despacho de etiquetas. Se utiliza en la biblioteca estándar para etiquetas de categoría de iteradores , con el fin de seleccionar algoritmos que pueden ser más eficientes con ciertas categorías de iteradores. Por ejemplo, std::distance puede implementarse algo como esto: (de hecho, se implementa casi exactamente como esto en gnu libstdc ++, pero lo he modificado ligeramente para mejorar la legibilidad)

template<typename Iterator> typename iterator_traits<Iterator>::difference_type distance(Iterator first, Iterator last) { return __distance(first, last, typename iterator_traits<Iterator>::iterator_category()); }

Donde __distance es una función que está sobrecargada para comportarse de manera más eficiente para std::random_access_iterator_tag (que es una estructura vacía, pero que podría ser una clase) , simplemente usando el last - first lugar en lugar del comportamiento predeterminado de contar cuántos incrementos Tarda en llegar first al last .


Existe un patrón, utilizado para la protección de acceso, basado en ese tipo de clase: a veces se denomina patrón de clave de acceso (consulte también ¿equivalente de amigo granular limpio de C ++? (Respuesta: Idioma del abogado-cliente) y cómo denominar a este acceso clave orientado a la protección de acceso). patrón? ).

Solo un amigo de la clase clave tiene acceso a protectedMethod() :

// All members set by default to private class PassKey { friend class Foo; PassKey() {} }; class Bar { public: void protectedMethod(PassKey); }; class Foo { void do_stuff(Bar& b) { b.protectedMethod(PassKey()); // works, Foo is friend of PassKey } }; class Baz { void do_stuff(Bar& b) { b.protectedMethod(PassKey()); // error, PassKey() is private } };


No, no tiene sentido crear una clase sin una variable de miembro público y / o funciones, ya que no habría una manera de acceder a nada en la clase. Incluso si no se establece explícitamente, la herencia también es privada.

Claro, podrías usar el friend como se sugiere, pero crearía una convolución innecesaria.

Por otro lado, si usas struct y no class para definir una clase, entonces obtienes todo lo público. Eso puede tener sentido.

Por ejemplo :

struct MyHwMap { unsigned int field1 : 16; unsigned int field2 : 8; unsigned int fieldA : 24; };


Un caso ciertamente feo de muchos, muchos años atrás y no en C ++, pero la idea aún se aplicaría:

Hubo un error en la biblioteca de tiempo de ejecución. En realidad, arreglar el código ofensivo causaría otros problemas, así que escribí una rutina que encontró el código ofensivo y lo reemplazé con una versión que funcionó. La encarnación original no tenía ninguna interfaz más allá de su creación.