funciones - ¿Cuándo deberías usar una clase vs una estructura en C++?
struct vs class c# (25)
¿Cuándo elegirías usar struct y cuándo usar class en C ++?
Uso struct
cuando defino functors
y POD
. De lo contrario yo uso la class
.
// ''()'' is public by default!
struct mycompare : public std::binary_function<int, int, bool>
{
bool operator()(int first, int second)
{ return first < second; }
};
class mycompare : public std::binary_function<int, int, bool>
{
public:
bool operator()(int first, int second)
{ return first < second; }
};
¿En qué situaciones es mejor usar una struct
vs una class
en C ++?
Clase.
Los miembros de la clase son privados por defecto.
class test_one {
int main_one();
};
Es equivalente a
class test_one {
private:
int main_one();
};
Así que si lo intentas
int two = one.main_one();
main_one is private
un error: main_one is private
porque no es accesible. Podemos resolverlo inicializándolo especificando su público, es decir,
class test_one {
public:
int main_one();
};
Struct.
Una estructura es una clase donde los miembros son públicos por defecto.
struct test_one {
int main_one;
};
Significa main_one
es privado, es decir
class test_one {
public:
int main_one;
};
Utilizo estructuras para estructuras de datos donde los miembros pueden tomar cualquier valor, así es más fácil.
Como todos dicen, la única diferencia real es el acceso predeterminado. Pero particularmente uso struct cuando no quiero ningún tipo de encapsulación con una clase de datos simple, incluso si implemento algunos métodos de ayuda. Por ejemplo, cuando necesito algo como esto:
struct myvec {
int x;
int y;
int z;
int length() {return x+y+z;}
};
Como todos los demás señalan, en realidad solo hay dos diferencias reales de idioma:
-
struct
defecto acceso público y laclass
defecto es acceso privado. - Al heredar,
struct
valores predeterminados a herenciapublic
yclass
valores predeterminados a herenciaprivate
. (Irónicamente, como ocurre con muchas cosas en C ++, el valor predeterminado es al revés:public
herenciapublic
es, con mucho, la opción más común, pero las personas rara vez declaran lasstruct
solo para ahorrar al escribir la palabra clave "public
".
Pero la diferencia real en la práctica es entre una class
/ struct
que declara un constructor / destructor y una que no lo hace. Hay ciertas garantías para un tipo de POD de "datos antiguos" que ya no se aplican una vez que se hace cargo de la construcción de la clase. Para mantener clara esta distinción, muchas personas solo usan struct
para los tipos de POD y, si van a agregar algún método, usan las class
. La diferencia entre los dos fragmentos a continuación no tiene sentido:
class X
{
public:
// ...
};
struct X
{
// ...
};
(Por cierto, aquí hay un hilo con algunas buenas explicaciones sobre lo que realmente significa "tipo de POD": ¿Qué son los tipos de POD en C ++? )
Desde el C ++ FAQ Lite :
Los miembros y las clases base de una estructura son públicos por defecto, mientras que en clase, por defecto son privados. Nota: debe hacer que sus clases base sean explícitamente públicas, privadas o protegidas, en lugar de confiar en los valores predeterminados.
estructura y clase son funcionalmente equivalentes.
OK, basta de esa charla de techno reluciente. Emocionalmente, la mayoría de los desarrolladores hacen una fuerte distinción entre una clase y una estructura. Una estructura simplemente se siente como una pila abierta de bits con muy poca forma de encapsulación o funcionalidad. Una clase se siente como un miembro vivo y responsable de la sociedad con servicios inteligentes, una barrera de encapsulación fuerte y una interfaz bien definida. Ya que esa es la connotación que la mayoría de la gente ya tiene, probablemente debería usar la palabra clave struct si tiene una clase que tiene muy pocos métodos y datos públicos (¡tales cosas existen en sistemas bien diseñados!), Pero de lo contrario probablemente debería usar la clase palabra clave.
Hay muchas ideas erróneas en las respuestas existentes.
Tanto la class
como la struct
declaran una clase.
Sí, es posible que deba reorganizar sus palabras clave de modificación de acceso dentro de la definición de la clase, dependiendo de la palabra clave que utilizó para declarar la clase.
Pero, más allá de la sintaxis, la única razón para elegir una sobre la otra es la convención / estilo / preferencia.
A algunas personas les gusta seguir con la palabra clave struct
para clases sin funciones miembro, porque la definición resultante "parece" una estructura simple de C.
De manera similar, a algunas personas les gusta usar la palabra clave de class
para clases con funciones miembro y datos private
, porque dice "clase" en ella y, por lo tanto, parecen ejemplos de su libro favorito sobre programación orientada a objetos.
La realidad es que esto depende completamente de usted y su equipo, y literalmente no hará ninguna diferencia en su programa.
Las siguientes dos clases son absolutamente equivalentes en todos los sentidos, excepto su nombre:
struct Foo
{
int x;
};
class Bar
{
public:
int x;
};
Incluso puedes cambiar las palabras clave al redeclarar:
class Foo;
struct Bar;
(aunque algunos compiladores emitirán una advertencia cuando hagas esto, en el supuesto de que probablemente no tengas la intención de hacer algo tan confuso y que, por lo tanto, se te pida que revises tu código).
y las siguientes expresiones se evalúan como verdaderas:
std::is_class<Foo>::value
std::is_class<Bar>::value
Sin embargo, tenga en cuenta que no puede cambiar las palabras clave al redefinir ; esto solo se debe a que (según la regla de una definición) las definiciones de clase duplicadas en las unidades de traducción deben "consistir en la misma secuencia de tokens" . Esto significa que ni siquiera puedes intercambiar const int member;
con int const member;
, y no tiene nada que ver con la semántica de class
o struct
.
La única vez que uso una estructura en lugar de una clase es cuando declaro un funtor justo antes de usarlo en una llamada de función y quiero minimizar la sintaxis para mayor claridad. p.ej:
struct Compare { bool operator() { ... } };
std::sort(collection.begin(), collection.end(), Compare());
Las diferencias entre una class
y una struct
en C ++ son que las estructuras tienen miembros public
predeterminados y las bases y las clases tienen miembros private
y bases predeterminados. Tanto las clases como las estructuras pueden tener una mezcla de miembros public
, protected
y private
, pueden usar la herencia y pueden tener funciones de miembro.
Recomendaría el uso de estructuras como estructuras de datos antiguos sin ninguna característica similar a una clase, y el uso de clases como estructuras de datos agregados con datos private
y funciones de miembro.
Las estructuras ( PODs , más generalmente) son útiles cuando se proporciona una interfaz compatible con C con una implementación de C ++, ya que son portátiles a través de los límites de idioma y los formatos de vinculador.
Si eso no te preocupa, supongo que el uso de "struct" en lugar de "class" es un buen comunicador de intenciones (como lo dijo @ZeroSignal arriba). Las estructuras también tienen una semántica de copia más predecible, por lo que son útiles para los datos que pretende escribir en medios externos o enviar a través del cable.
Las estructuras también son útiles para varias tareas de metaprogramación, como plantillas de rasgos que solo exponen un conjunto de definiciones de tipo dependientes:
template <typename T> struct type_traits {
typedef T type;
typedef T::iterator_type iterator_type;
...
};
... Pero eso es solo aprovechar el nivel de protección predeterminado de struct que es público ...
Las estructuras por defecto tienen acceso público y las clases por defecto tienen acceso privado.
Personalmente uso estructuras para objetos de transferencia de datos o como objetos de valor. Cuando se usa como tal, declaro todos los miembros como constantes para evitar modificaciones por otro código.
Las funciones de acceso no son la única diferencia entre estructuras y clases. Una estructura es mejor para los tipos POD (datos antiguos), ya que es más fácil de administrar para el compilador y el programador. Para los principiantes que no usan programación orientada a objetos, usar una estructura está bien.
Nunca uso "struct" en C ++.
Nunca puedo imaginar un escenario en el que usarías una estructura cuando quieres miembros privados, a menos que intentes ser confuso.
Parece que el uso de estructuras es más una indicación sintáctica de cómo se utilizarán los datos, pero prefiero hacer una clase y tratar de hacerlo explícito en el nombre de la clase, o por medio de comentarios.
P.ej
class PublicInputData {
//data members
};
Para C ++, realmente no hay mucha diferencia entre estructuras y clases. La principal diferencia funcional es que los miembros de una estructura son públicos por defecto, mientras que son privados por defecto en las clases. De lo contrario, en lo que se refiere al idioma, son equivalentes.
Dicho esto, tiendo a usar estructuras en C ++ como lo hago en C #, similar a lo que Brian ha dicho. Las estructuras son simples contenedores de datos, mientras que las clases se usan para objetos que necesitan actuar sobre los datos además de mantenerlos.
Para responder a mi propia pregunta (sin vergüenza), Como ya se mencionó, los privilegios de acceso son la única diferencia entre ellos en C ++.
Tiendo a usar una estructura solo para almacenamiento de datos. Permitiré que obtenga algunas funciones de ayuda si facilita el trabajo con los datos. Sin embargo, tan pronto como los datos requieran control de flujo (es decir, captadores / definidores que mantienen o protegen un estado interno) o comienzan a adquirir cualquier funcionalidad principal (básicamente más como objetos), se actualizará a una clase para comunicar mejor la intención.
Pensé que Structs estaba pensado como una estructura de datos (como una matriz de información de tipo multi-datos) y que las clases se incorporaron para el empaquetado de código (como colecciones de subrutinas y funciones).
:(
Puede usar "struct" en C ++ si está escribiendo una biblioteca cuyos elementos internos son C ++ pero la API puede llamarse mediante el código C o C ++. Simplemente crea un único encabezado que contiene estructuras y funciones de la API global que expone a los códigos C y C ++ como esto:
// C access Header to a C++ library
#ifdef __cpp
extern "C" {
#endif
// Put your C struct''s here
struct foo
{
...
};
// NOTE: the typedef is used because C does not automatically generate
// a typedef with the same name as a struct like C++.
typedef struct foo foo;
// Put your C API functions here
void bar(foo *fun);
#ifdef __cpp
}
#endif
Luego, puede escribir una barra de funciones () en un archivo C ++ utilizando el código C ++ y hacer que se pueda llamar desde C y los dos mundos pueden compartir datos a través de las estructuras declaradas. Por supuesto, hay otras advertencias al mezclar C y C ++, pero este es un ejemplo simplificado.
Recomiendo no mezclar struct
y class
.
Como han señalado otros
- Ambos son equivalentes aparte de la visibilidad por defecto.
- puede haber razones para ser forzado a usar una o la otra por cualquier razón
A menos que sea forzado, vaya solo con struct
o solo con class
porque le protege de problemas de enlace críptico sin costo .
Si reenvías declara algo. como la class X;
y luego struct X { ... }
como struct X { ... }
puede funcionar en algunos enlazadores (por ejemplo, g ++) y puede fallar en otros (por ejemplo, MSVC), por lo que se encontrará en el infierno de los desarrolladores. Como no hay razón para mezclar struct
y class
, ¿por qué uno debería hacer que los pensamientos sean más complicados y preocuparse por si esa cosa era una class
o struct
?
Son casi lo mismo. Gracias a la magia de C ++, una estructura puede contener funciones, usar herencia, creada usando "nuevo" y así como una clase
La única diferencia funcional es que una clase comienza con derechos de acceso privados, mientras que una estructura comienza con público. Esta es la compatibilidad hacia atrás con C.
En la práctica, siempre he usado estructuras como portadores de datos y clases como objetos.
Técnicamente, ambos son iguales en C ++; por ejemplo, es posible que una estructura tenga operadores sobrecargados, etc.
Sin embargo :
Utilizo structs cuando deseo pasar información de varios tipos simultáneamente. Utilizo clases cuando trato con un objeto "funcional".
Espero eso ayude.
#include <string>
#include <map>
using namespace std;
struct student
{
int age;
string name;
map<string, int> grades
};
class ClassRoom
{
typedef map<string, student> student_map;
public :
student getStudentByName(string name) const
{ student_map::const_iterator m_it = students.find(name); return m_it->second; }
private :
student_map students;
};
Por ejemplo, estoy devolviendo a un estudiante de struct en los métodos get ... () aquí - disfrútalo.
Todos los miembros de la clase son privados por defecto y todos los miembros de la estructura son públicos por defecto. La clase tiene bases privadas predeterminadas y Struct tiene bases públicas predeterminadas. Struct en el caso de C no puede tener funciones miembro, mientras que en el caso de C ++ podemos agregar funciones miembro a la estructura. Aparte de estas diferencias, no encuentro nada sorprendente en ellas.
Un lugar donde una estructura me ha sido útil es cuando tengo un sistema que recibe mensajes de formato fijo (por ejemplo, un puerto serie) de otro sistema. Puede convertir el flujo de bytes en una estructura que define sus campos y luego acceder fácilmente a los campos.
typedef struct
{
int messageId;
int messageCounter;
int messageData;
} tMessageType;
void processMessage(unsigned char *rawMessage)
{
tMessageType *messageFields = (tMessageType *)rawMessage;
printf("MessageId is %d/n", messageFields->messageId);
}
Obviamente, esto es lo mismo que haría en C, pero creo que la sobrecarga de tener que descifrar el mensaje en una clase generalmente no vale la pena.
Una ventaja de la struct
sobre class
es que guarda una línea de código, si se adhiere a "los primeros miembros públicos, luego los privados". En este sentido, encuentro inútil la class
palabras clave.
Aquí hay otra razón para usar solo struct
y nunca class
. Algunas pautas de estilo de código para C ++ sugieren el uso de letras pequeñas para las macros de función, la razón es que cuando la macro se convierte en una función en línea, el nombre no debería ser cambiado. Igual que aquí. Tiene su estructura agradable de estilo C y, un día, descubre que necesita agregar un constructor o algún método conveniente. ¿Lo cambias a una class
? ¿En todos lados?
Distinguir entre struct
y class
es simplemente una molestia, meterse en la forma de hacer lo que deberíamos estar haciendo: la programación. Como muchos de los problemas de C ++, surge del fuerte deseo de compatibilidad hacia atrás.
Uso struct solo cuando necesito mantener algunos datos sin ninguna función miembro asociada (para operar en los datos del miembro) y para acceder a las variables de datos directamente.
Por ejemplo: leer / escribir datos de archivos y flujos de socket, etc. Pasar argumentos de función en una estructura donde los argumentos de función son demasiados y la sintaxis de la función parece demasiado larga.
Técnicamente, no hay una gran diferencia entre clase y estructura, excepto la accesibilidad predeterminada. Más sobre esto depende del estilo de programación cómo lo uses.
Utilizo estructuras cuando necesito crear un tipo de POD o functor.
son lo mismo con diferentes valores predeterminados (privado por defecto para la class
y público por defecto para la struct
), por lo que en teoría son totalmente intercambiables.
Entonces, si solo quiero empaquetar alguna información para moverme, uso una estructura, incluso si pongo algunos métodos allí (pero no muchos). Si es una cosa en su mayoría opaca, donde el uso principal sería a través de métodos, y no directamente a los miembros de datos, uso una clase completa.