¿Cuándo debería usar una clase frente a una estructura en C ++?

1104

¿En qué escenarios es mejor usar a structvs a classen C ++?

19
  • 64
    Esto no solo se aplica a C ++, sino a cualquier lenguaje que proporcione estructuras y clases. 10 de septiembre de 2008 a las 16:31
  • 4
    Sigo en desacuerdo: abordo esta cuestión de forma semántica. Tal vez haya algunas diferencias técnicas, pero semánticamente, no lo son. Las estructuras son realmente útiles para crear tipos de valor, las clases no. 10 de septiembre de 2008 a las 17:22
  • 9
    Creo que no hay ninguna razón seria para usar estructuras en C ++. Para mí, las estructuras son otra "característica" redundante de C ++ que existe solo por compatibilidad con C, como typedefs. Estos no existirían si C ++ no se tratara inicialmente como una extensión de C y se diseñara desde cero, como Java. En general, encuentro que muchas de las cosas más extrañas de C ++ tienen que ver con la compatibilidad con C.
    Kostas
    26/06/09 a las 11:31
  • 7
    Struct: para POD (datos antiguos sin formato) y la accesibilidad de todos los miembros es pública. Clase: cuando necesita una mejor encapsulación y necesita funciones miembro para trabajar con el estado de la clase. 28 de julio de 2009 a las 3:51
  • 6
    Esto es cierto solo por convención. No hay ninguna diferencia, aparte de la encapsulación predeterminada. 28 de julio de 2009 a las 4:46
935

Las diferencias entre ay classa structen C ++ son:

  • structlos miembros y las clases / estructuras base son publicpor defecto.
  • class los miembros y las clases / puntales base son los privatepredeterminados.

Tanto las clases como las estructuras pueden tener una combinación de public, protectedy los privatemiembros pueden usar herencia y pueden tener funciones miembro.

Te recomendaria:

  • utilizar structpara estructuras de datos antiguos sin características de clase;
  • use classcuando haga uso de características como miembros privateo protected, constructores y operadores no predeterminados, etc.
dieciséis
  • 112
    Una estructura sin modificadores o métodos se llama estructura POD, que existe como una interfaz compatible con las bibliotecas de C, ya que (supuestamente) se garantiza que se presentará como si fuera una estructura de C. Sin embargo, aparte de esta única excepción, la única diferencia es la indicada. 18 de septiembre de 2008 a las 14:22
  • 34
    @ workmad3: el nombre es engañoso, pero 9/4 (C ++ 03) dice: "Una estructura POD es una clase agregada que no tiene miembros de datos no estáticos de tipo non-POD-struct, non-POD-union (o matriz de tales tipos) o referencia, y no tiene un operador de asignación de copia definido por el usuario ni un destructor definido por el usuario ". No hay ninguna restricción sobre el uso de la clave de clase "struct" ni ninguna restricción sobre el uso de "público" (consulte 8.5.1 / 1 para conocer los requisitos agregados). Esta no es una diferencia entre "estructura" y "clase".
    Roger Pate
    22/09/10 a las 20:31
  • 6
    Su uso de "agregado" podría malinterpretarse, dada la definición de la norma. :)
    Roger Pate
    22/09/10 a las 20:32
  • 3
    De acuerdo con el libro "Principios y práctica" de Stroustrup: "las estructuras deben usarse principalmente donde los miembros pueden tomar cualquier valor" (es decir, donde no se puede definir un invariante de clase significativo)
    antibus
    30/12/14 a las 13:57
  • 6
    Por supuesto, puede usar clases cuando interactúe con C. No hay diferencia entre clases y estructuras. Las estructuras son clases; solo el acceso predeterminado se cambia de privado a público. 17 de marzo de 2016 a las 12:58
261

Como todos los demás señalan, en realidad solo hay dos diferencias de idioma reales:

  • structpor defecto es el acceso público y por classdefecto el acceso privado.
  • Al heredar, el valor structpredeterminado es la publicherencia y el valor classpredeterminado es la privateherencia. (Irónicamente, como con tantas cosas en C ++, el valor predeterminado es al revés: la publicherencia es, con mucho, la opción más común, pero la gente rara vez declara structs solo para ahorrar al escribir la publicpalabra clave " ".

Pero la diferencia real en la práctica es entre un class/ structque declara un constructor / destructor y uno que no lo hace. Hay ciertas garantías para un tipo de POD de "datos antiguos sin formato", 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 deliberadamente solo usan structs para tipos de POD y, si van a agregar algún método, usan classes. 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 POD": ¿Qué son los tipos POD en C ++? )

5
  • Buen ejemplo sobre las diferencias de herencia: aquí . 13/09/10 a las 13:33
  • 10
    Si usa structo classno tiene relación con si su objeto es POD o si debe definir un constructor / destructor de copia. Las funciones de los miembros tampoco tienen nada que ver con que algo sea POD. Al releer lo que escribió, veo que no está sugiriendo lo contrario, pero la redacción actual es confusa. 23/11/2014 a las 0:50
  • 1
    @DavidStone Básicamente, se supone que se garantiza que las estructuras POD son compatibles con versiones anteriores del código C y, por lo tanto, se supone que están diseñadas como estructuras de estilo C. 21/02/2016 a las 0:16
  • @juanchopanza ¿cómo es eso? ¿Hay otras diferencias que conozca?
    rdelfin
    29 de ene a las 11:17
  • 1
    @rdelfin Creo que debo haber leído mal el párrafo, porque la pregunta es sobre las diferencias entre structy classy cuando se trata del diseño del objeto, no hay ninguna. Lo de POD también ha cambiado un poco desde C ++ 11. Sin embargo, las viñetas son correctas. se trata solo de los valores predeterminados cuando usa cualquiera de las palabras clave para definir una clase. 29 de ene a las 21:11
225

Hay muchos conceptos erróneos en las respuestas existentes.

Ambos classy structdeclarar una clase.

Sí, es posible que deba reorganizar su acceso modificando las palabras clave 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 quedarse con la structpalabra clave 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 classpalabra clave para clases con funciones miembro y privatedatos, porque dice "clase" y, por lo tanto, parece un ejemplo 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 en su nombre:

struct Foo
{
   int x;
};

class Bar
{
public:
   int x;
};

Incluso puede cambiar las palabras clave al volver a declarar:

class Foo;
struct Bar;

(aunque esto rompe las compilaciones de Visual Studio debido a una no conformidad, por lo que el compilador emitirá una advertencia cuando haga esto).

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 se debe únicamente a que (según la regla de una definición) las definiciones de clases duplicadas en las unidades de traducción deben "constar de la misma secuencia de tokens" . Esto significa que ni siquiera puede intercambiar const int member;con int const member;y no tiene nada que ver con la semántica de classo struct.

6
  • 21
    Esto fue muy informativo y, sinceramente, mi respuesta favorita. Todos los demás los tratan como entidades separadas, cuando bajo el capó, son lo mismo. Me pregunto si una definición de estructura en el entorno Arduino se considera una clase cpp, ya que se compila con g ++. 24/04/2017 a las 5:07
  • 4
    @Ben Por supuesto que lo es. El compilador de Arduino compila C ++; ese es el final. 22 de mayo de 2017 a las 16:52
  • 10
    Entonces, si lo entiendo bien: siempre que sus modificadores de visibilidad sean explícitos, no se omitan, no importa. Podrías escribir una gran aplicación en C ++ usando nada más que estructuras; o puede revisar y cambiar cada caso de estructura a clase. Siempre que no utilice la visibilidad predeterminada, las aplicaciones serán exactamente las mismas. 29 de septiembre de 2017 a las 16:36
  • No estoy convencido de que una unidad de traducción de un programa C ++ pueda tener la declaración completa class foo { public: ... };y otra pueda tener, lo struct foo { ... };que debería ser cierto según la afirmación "absolutamente equivalente". Llega a la razón que las declaraciones incompletas struct foo;y class foo;son intercambiables. Estos no especifican el cuerpo de la clase, por lo que no dicen nada sobre el diseño de acceso.
    Kaz
    15 de febrero de 2018 a las 2:36
  • @Kaz: Tienes razón: si las definiciones fueran literalmente del mismo tipo, deben ser léxicamente idénticas para que el comportamiento esté bien definido. La clave struct y -clave de clase son de otra manera lógicamente aunque intercambiable (donde la semántica no se ven afectados), y Fooy Barson todavía equivalente / tipos idénticos. Me aseguré de decir "al redeclarar " y dar un ejemplo. Ahora que lo pienso, aclararé esto en la respuesta para asegurarme de no engañar a la gente sobre UB. 15 feb 2018 a las 12:31
57

La única vez que uso una estructura en lugar de una clase es cuando declaro un functor justo antes de usarlo en una llamada de función y quiero minimizar la sintaxis en aras de la claridad. p.ej:

struct Compare { bool operator() { ... } };
std::sort(collection.begin(), collection.end(), Compare()); 
1
42

Desde C ++ FAQ Lite :

The members and base classes of a struct are public by default, while in class, they default to private. Note: you should make your base classes explicitly public, private, or protected, rather than relying on the defaults.

struct and class are otherwise functionally equivalent.

OK, enough of that squeaky clean techno talk. Emotionally, most developers make a strong distinction between a class and a struct. A struct simply feels like an open pile of bits with very little in the way of encapsulation or functionality. A class feels like a living and responsible member of society with intelligent services, a strong encapsulation barrier, and a well defined interface. Since that's the connotation most people already have, you should probably use the struct keyword if you have a class that has very few methods and has public data (such things do exist in well designed systems!), but otherwise you should probably use the class keyword.

4
  • 1
    No entiendo por qué dicen que la estructura y la clase son funcionalmente iguales, pero dicen que prefieren una sobre la otra en ciertos casos sin ningún tipo de razonamiento.
    deetz
    12/10/2017 a las 6:33
  • 5
    La razón es la convención. Al compilador no le importa cuál use, pero a otro desarrollador que mire su código le resultará más fácil entender lo que quiere decir. 13/10/2017 a las 7:43
  • 4
    @deetz: Todo el tercer párrafo es razonamiento. 26/02/18 a las 2:13
  • Vaya, viniendo de la 'vieja escuela', no tenía idea de que una estructura pudiera tener métodos e incluso herencia. Siempre he usado struct para cuando utilizo solo datos sin métodos y generalmente es cuando se trata de código API que necesita la estructura. ¿Pueden las estructuras también admitir herencia múltiple? 17 dic 2019 a las 16:07
23

Puede usar "struct" en C ++ si está escribiendo una biblioteca cuyas partes internas son C ++ pero la API puede ser llamada por código C o C ++. Simplemente crea un solo encabezado que contiene estructuras y funciones API globales que expone al código C y C ++ como este:

// 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 función bar () en un archivo C ++ usando código C ++ y hacerlo invocable 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.

1
  • 3
    La mejor respuesta adecuada. La compatibilidad con C es realmente la razón más importante. todas las demás cosas, como el acceso predeterminado, son esotéricas. 31 de mayo de 2015 a las 22:32
23

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 defina 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 encuentro que la sobrecarga de tener que decodificar el mensaje en una clase generalmente no vale la pena.

9
  • Lo mismo se puede lograr en C. 16 de junio de 2009 a las 8:48
  • 13
    O simplemente podría implementar operator >>en una clase en lugar de escribir la processMessagefunción, lo que haría que su C ++ se pareciera más a C ++ adecuado y menos a C. 20/06/10 a las 18:29
  • 2
    Además del hecho de que no es portátil entre diferentes sistemas, esto viola las reglas de aliasing, por lo que no se garantiza que funcione incluso dentro de una única arquitectura. 22 de mayo de 2017 a las 16:58
  • 1
    @underscore_d Bastante portátil durante la vida útil de un proyecto o base de código para un sistema integrado, y un ADC no cambiará su conjunto de registros durante 30 años. Hace el trabajo, es de ciclo único y fácilmente comprobable, y se puede entregar a los controladores del kernel, void*llamadas al sistema y pasar entre C y C ++, digo ganar-ganar.
    crasic
    12 dic 2017 a las 9:55
  • 1
    @jacwah Eh, buen punto. El aliasing no será un problema aquí porque uno de los punteros es un chartipo, que está exento de aliasing. Sin embargo, todavía hay un problema, aunque diferente: enviar a char*a un tipo diferente, si realmente no había ningún objeto de este último tipo ya inicializado en esa dirección, es UB ya que viola las reglas de por vida. Afaik, incluso si el tipo de destino es trivialmente construible, solo tener memoria asignada no es suficiente para que C ++ permita formalmente tratar esa memoria como ese tipo. 4 de ene. De 2018 a las 15:35
19

Como dice todo el mundo, la única diferencia real es el acceso por defecto. 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 auxiliares. Por ejemplo, cuando necesito algo como esto:

struct myvec {
    int x;
    int y;
    int z;

    int length() {return x+y+z;}
};
1
  • 2
    +1 por dar un ejemplo de una estructura con algunas funciones miembro que no parecen haber "quitado la estructura". 5 feb 2017 a las 19:33
11

Para responder a mi propia pregunta (descaradamente), como ya se mencionó, los privilegios de acceso son la única diferencia entre ellos en C ++.

Tiendo a usar una estructura solo para el almacenamiento de datos. Permitiré que obtenga algunas funciones auxiliares 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 alguna funcionalidad importante (básicamente más similar a un objeto), se 'actualizará' a una clase para comunicar mejor la intención.

11

Las estructuras ( POD , de manera más general) 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 las fronteras del idioma y los formatos de enlace.

Si eso no le preocupa, entonces supongo que el uso de la "estructura" en lugar de la "clase" es un buen comunicador de intenciones (como @ZeroSignal dijo arriba). Las estructuras también tienen una semántica de copia más predecible, por lo que son útiles para los datos que desea 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 montón de typedefs dependientes:

template <typename T> struct type_traits {
  typedef T type;
  typedef T::iterator_type iterator_type;
  ...
};

... Pero eso es en realidad aprovechar que el nivel de protección predeterminado de struct es público ...

3
  • 1
    Ese no es el uso correcto de POD. Una estructura (o clase) puede ser estructura POD si (y solo si) contiene SÓLO miembros POD. 5 mar 09 a las 8:07
  • 4
    "Semántica de copia predecible": La simántica es la misma que para la clase (y tiene los mismos problemas (copia superficial)). 5 mar 09 a las 8:09
  • 2
    Esta publicación te haría creer (con suerte por accidente) que todas las estructuras son POD. Esto no es del todo cierto. Espero que esto no engañe a la gente. 30/07/2014 a las 15:41
10

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 de forma predeterminada, mientras que en las clases son privados de forma predeterminada. De lo contrario, en lo que respecta al idioma, son equivalentes.

Dicho esto, tiendo a usar estructuras en C ++ como lo hago en C #, similar a lo que ha dicho Brian. Las estructuras son contenedores de datos simples, mientras que las clases se utilizan para objetos que necesitan actuar sobre los datos además de simplemente retenerlos.

6

Como otros han señalado

  • ambos son equivalentes aparte de la visibilidad predeterminada
  • puede haber razones para verse obligado a usar uno u otro por cualquier motivo

Hay una recomendación clara sobre cuándo usarla de Stroustrup / Sutter:

Use class if the class has an invariant; use struct if the data members can vary independently

Sin embargo, tenga en cuenta que no es aconsejable reenviar declare algo. como una clase ( class X;) y definirlo como struct ( 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.

6
  • 1
    ¿Puede describir estos problemas del enlazador? 23 feb 2019 a las 18:30
  • @LightnessRacesinOrbit No puedo, desafortunadamente. Ni siquiera soy capaz de elaborar un ejemplo. Lo trivial class Foo; struct Foo { void bar() {} }; int main() { Foo().bar(); }no solo se compila y se ejecuta con MSVC 2017, sino que incluso produce una advertencia clara que Foose declaró structpero se definió como class. Pero también recuerdo claramente que a nuestro equipo le costó medio día encontrar ese estúpido error. No estoy seguro de qué versión de MSVC usamos en ese entonces.
    pasbi
    23 feb 2019 a las 21:39
  • El enlazador ni siquiera debería saber si usó classo structen una declaración hacia adelante, y los dos son libremente intercambiables según el estándar (aunque se sabe que VS advierte; siempre asumí que era solo para evitar errores aparentes del programador). Algo no huele bien aquí. ¿Estás seguro de que no se trataba de un error de infracción de ODR? 23 feb 2019 a las 21:42
  • 1
    Hmm, parece que VS no cumple en este sentido (figura) 23 feb 2019 a las 21:44
  • No recuerdo exactamente. El problema no ocurrió directamente en una aplicación, sino en una biblioteca que se utilizó en un gtest. Solo sé que el enlazador produjo errores incomprensibles (¿LNK ???). Una vez que reemplacé los struct-forwards por class-forwards, los problemas desaparecieron. A partir de hoy, a mí también me parece extraño. Me alegraría si pudiera aclararlo un poco.
    pasbi
    23 feb 2019 a las 22:14
5

Son prácticamente lo mismo. Gracias a la magia de C ++, una estructura puede contener funciones, usar herencia, crear usando "nuevo" y así sucesivamente 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. Este es el mantenimiento de la compatibilidad con versiones anteriores de C.

En la práctica, siempre he usado estructuras como contenedores de datos y clases como objetos.

5

Una ventaja de structover classes que guarda una línea de código, si se adhiere a "primero miembros públicos, luego privados". En este sentido, encuentro la palabra clave classinútil.

Aquí hay otra razón para usar solo structy nunca class. Algunas pautas de estilo de código para C ++ sugieren el uso de letras minúsculas para macros de funciones, con la razón de que cuando la macro se convierte en una función en línea, no es necesario cambiar el nombre. Aquí igual. Tienes tu estructura de estilo C agradable y un día, descubres que necesitas agregar un constructor o algún método conveniente. ¿Lo cambia a a class? ¿En todos lados?

Distinguir entre structs y classes es demasiado complicado, meterse en la forma de hacer lo que deberíamos hacer: programar. Como muchos de los problemas de C ++, surge del fuerte deseo de compatibilidad con versiones anteriores.

4
  • ¿Por qué necesitarías cambiarlo a class? ¿Pensaste que una clase definida con la structpalabra clave no puede tener funciones miembro o un constructor? 26/02/18 a las 2:16
  • @LightnessRacesinOrbit debido a 1. consistencia y 2. algunos analizadores estáticos se quejan de la violación de 1.
    Vorac
    27/02/18 a las 15:27
  • Eso no sigue. ¿A qué otras "consistencias" te adhieres? Cada clase con un miembro llamado joe()debe definirse con la classpalabra clave? Cada clase con al menos 4 intmiembros debe definirse con la structpalabra clave? 27/02/18 a las 17:11
  • @LightnessRacesinOrbit Me refiero a la expresión "los agregados POD se definen con struct, los agregados con métodos se definen con class". Demasiada molestia.
    Vorac
    28/02/19 a las 7:37
4

Clase.

Los miembros de la clase son privados de forma predeterminada.

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();

Obtendremos un error: main_one is privateporque no es accesible. Podemos resolverlo inicializándolo especificando que es un público, es decir.

class test_one {
  public:
    int main_one();
};

Struct.

Una estructura es una clase en la que los miembros son públicos de forma predeterminada.

struct test_one {
    int main_one;
};

Los medios main_oneson privados, es decir

class test_one {
  public:
    int main_one;
};

Utilizo estructuras para estructuras de datos donde los miembros pueden tomar cualquier valor, es más fácil de esa manera.

4

Ambos structy classson iguales bajo el capó, aunque con diferentes valores predeterminados en cuanto a visibilidad, el structvalor predeterminado es público y el classpredeterminado es privado. Puede cambiar uno para que sea el otro con el uso apropiado de privatey public. Ambos permiten herencia, métodos, constructores, destructores y todas las demás ventajas de un lenguaje orientado a objetos.

Sin embargo, una gran diferencia entre los dos es que, structcomo palabra clave, se admite en C mientras classque no. Esto significa que se puede usar una structen un archivo de inclusión que puede ser #includeya sea en C ++ o C, siempre que el structes un estilo C llanura structy todo lo demás en el archivo de inclusión es compatible con C, es decir, no C ++ palabras clave específicas, tales como private, public, sin métodos, sin herencia, etc., etc., etc.

El estilo AC structse puede usar con otras interfaces que admiten el uso del estilo C structpara transportar datos de un lado a otro a través de la interfaz.

El estilo AC structes una especie de plantilla (no una plantilla de C ++, sino un patrón o plantilla) que describe el diseño de un área de memoria. Con los años las interfaces utilizable a partir de C y C con los plug-ins (aquí le está mirando Java y Python y Visual Basic) se han creado algunas de las cuales trabaja con el estilo C struct.

2
  • Esta respuesta se contradice: son "los mismos bajo el capó", pero hay "una gran diferencia". ¿Eh? Si el C ++ trata de implementación la struct especialmente para mantener la compatibilidad, como se describe, a continuación, que son no necesariamente el mismo "bajo el capó". El resto de la descripción es claro y compatible con otras respuestas y comentarios, pero si hay una diferencia, simplemente explíquelo directamente sin tener que retroceder desde la declaración de apertura. Al menos proporcione un contexto adecuado a la primera oración como "Si cualquiera de los tipos se usa completamente dentro de un contexto de C ++, entonces ..." 5/10/20 a las 2:48
  • El "mismo bajo el capó", el capó es interior de C ++; "gran diferencia" por encima del capó, fuera de C ++ propiamente dicho.
    Pablo H
    3 de septiembre a las 14:20
3

son lo mismo con diferentes valores predeterminados (privado por defecto para classy público por defecto para struct), por lo que en teoría son totalmente intercambiables.

Entonces, si solo quiero empaquetar algo de información para moverme, uso una estructura, incluso si coloco algunos métodos allí (pero no muchos). Si es algo mayormente opaco, donde el uso principal sería a través de métodos, y no directamente a los miembros de datos, uso una clase completa.

0
3

Las estructuras por defecto tienen acceso público y las clases por defecto tienen acceso privado.

Personalmente, utilizo 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.

1

Técnicamente, ambos son iguales en C ++; por ejemplo, es posible que una estructura tenga operadores sobrecargados, etc.

Sin embargo :

Utilizo estructuras cuando deseo pasar información de varios tipos simultáneamente. Utilizo clases cuando estoy tratando 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 un estudiante de struct en los métodos get ... () aquí: disfruta.

1

When would you choose to use struct and when to use class in C++?

Yo uso structcuando defino functorsy POD. De lo contrario utilizo 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; }
};
2
  • 1
    Esta respuesta muestra signos de edad :) std::binary_function<>no solo está en desuso, c ++ 17 incluso la elimina.
    sehe
    12/11/2017 a las 0:23
  • Realmente no es una sorpresa ya que fue escrito en la época de C ++ 03, un lenguaje definido hace 15 años. 26 feb 2018 a las 2:15
1

Utilizo estructuras cuando necesito crear un tipo o functor POD.

1

Todos los miembros de la clase son privados de forma predeterminada y todos los miembros de la estructura son públicos de forma predeterminada. La clase tiene bases privadas predeterminadas y Struct tiene bases públicas predeterminadas. La estructura en el caso de C no puede tener funciones miembro, mientras que, como en el caso de C ++, podemos añadir funciones miembro a la estructura. Aparte de estas diferencias, no encuentro nada sorprendente en ellas.

1

Solo para abordar esto desde una perspectiva C ++ 20 Standardese (trabajando desde N4860 ) ...

Una clase es un tipo. Las palabras clave " class" y " struct" (y " union") son, en la gramática de C ++, claves de clase , y el único significado funcional de la elección de classo structes:

The class-key determines whether ... access is public or private by default (11.9).

Accesibilidad predeterminada del miembro de datos

Que la classpalabra clave da como resultado miembros privados por defecto, y la palabra clave `struct da como resultado miembros públicos por defecto, está documentado por los ejemplos en 11.9.1:

class X { int a; // X::a is private by default: class used

... vs ...

struct S { int a; // S::a is public by default: struct used

Accesibilidad predeterminada de la clase base

1.9 también dice:

In the absence of an access-specifier for a base class, public is assumed when the derived class is defined with the class-key struct and private is assumed when the class is defined with the class-key class.

Circunstancias en las que se requiere el uso constante de estructura o clase ...

Hay un requisito:

In a redeclaration, partial specialization, explicit specialization or explicit instantiation of a class template, the class-key shall agree in kind with the original class template declaration (9.2.8.3).

...in any elaborated-type-specifier, the enum keyword shall be used to refer to an enumeration (9.7.1), the union class-key shall be used to refer to a union (11.5), and either the class or struct class-key shall be used to refer to a non-union class (11.1).

Se proporciona el siguiente ejemplo (de cuándo no se requiere coherencia ):

struct S { } s; class S* p = &s; // OK

Aún así, algunos compiladores pueden advertir sobre esto.


Curiosamente, mientras que los tipos con los que crea struct, classy uniontodos se denominan "clases", tenemos ...

A standard-layout struct is a standard layout class defined with the class-key struct or the class-key class.

... así que en Standardese, cuando se habla de una estructura de diseño estándar, se usa "struct" para implicar "no una unión".

Tengo curiosidad por saber si hay un uso similar de "struct" en otra terminología, pero es un trabajo demasiado grande para hacer una búsqueda exhaustiva del Estándar. Comentarios sobre esa bienvenida.

1
  • Pensé que había alguna diferencia con respecto al "espacio de nombres typedef", donde, por compatibilidad con C, puede escribir typedef struct A Ay usar struct Ao simple Apara declarar / definir variables, etc., pero parece que ese no es el caso. Parece que puedes usar ambos structo classde esa manera.
    Pablo H
    3 de septiembre a las 14:27
0

Utilizo struct solo cuando necesito retener 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 conectores, etc. Pasar argumentos de función en una estructura donde los argumentos de la función son demasiados y la sintaxis de la función parece demasiado larga.

Técnicamente, no hay una gran diferencia entre la clase y la estructura, excepto la accesibilidad predeterminada. Más depende del estilo de programación de cómo lo use.

-5

Pensé que Structs tenía la intención de ser una estructura de datos (como una matriz de información de tipo de datos múltiples) y las clases estaban destinadas a empaquetar código (como colecciones de subrutinas y funciones).

:(

0
-8

Nunca uso "struct" en C ++.

Nunca puedo imaginar un escenario en el que usarías una estructura cuando quieras miembros privados, a menos que estés tratando de confundir intencionalmente.

Parece que el uso de estructuras es más una indicación sintáctica de cómo se usarán los datos, pero prefiero hacer una clase e intentar hacerlo explícito en el nombre de la clase o mediante comentarios.

P.ej

class PublicInputData {
    //data members
 };
2
  • Según yo, una "indicación sintáctica de cómo se usarán los datos" es una razón perfectamente válida para usar una estructura, especialmente si la alternativa es usar un comentario o un nombre en el nombre de la clase. 26/06/09 a las 11:41
  • 2
    ¿No structsería bastante explícito declarar un ya que los miembros de la clase serán, por defecto, públicos? 15 de septiembre de 2011 a las 4:57