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


En qué escenarios es mejor usar un struct vs a class en C ++?


721
2017-09-10 16:29


origen


Respuestas:


Diferencias entre una class y un struct en C ++ son que las estructuras tienen por defecto public miembros y bases y clases tienen valores predeterminados private miembros y bases. Tanto las clases como las estructuras pueden tener una mezcla de public, protected y private miembros, pueden usar herencia y pueden tener funciones miembro.

Recomendaría usar estructuras como estructuras de datos antiguos sin características de clase, y usar clases como estructuras de datos agregados con private datos y funciones de miembros.


620
2017-09-10 16:35



Como todos los demás observan, en realidad solo hay dos diferencias de lenguaje reales:

  • struct predeterminado para el acceso público y class predeterminado para el acceso privado.
  • Al heredar, struct predeterminado a public herencia y class predeterminado a private herencia. (Irónicamente, como con tantas cosas en C ++, el valor predeterminado es al revés: public la herencia es, con mucho, la opción más común, pero las personas rara vez declaran structs solo para ahorrar al tipear el "public"palabra clave.

Pero la diferencia real en la práctica es entre una class/struct que declara un constructor / destructor y uno que no. Existen ciertas garantías para un tipo de POD "de datos antiguos", que ya no se aplica una vez que se hace cargo de la construcción de la clase. Para mantener esta distinción clara, muchas personas solo usan deliberadamente structs para los tipos de POD, y, si van a agregar algún método, use 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 el "tipo POD": ¿Qué son los tipos de POD en C ++?)


173
2017-07-28 04:02



Hay muchas ideas erróneas en las respuestas existentes.

Ambos class y struct declara una clase

Sí, es posible que deba reorganizar las palabras clave que modifican el acceso dentro de la definición de clase, según la palabra clave que utilizó para declarar la clase.

Pero, más allá de la sintaxis, el solamente la razón para elegir una sobre la otra es la convención / estilo / preferencia.

A algunas personas les gusta quedarse con el struct palabra clave para clases sin funciones miembro, porque la definición resultante "parece" una estructura simple de C.

Del mismo modo, a algunas personas les gusta usar el class palabra clave para clases con funciones miembro y private datos, porque dice "clase" y por lo tanto se ve como ejemplos de su libro favorito sobre programación orientada a objetos.

La realidad es que esto depende completamente de usted y de su equipo, y literalmente no tendrá ninguna importancia para 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 redeclar:

class Foo;
struct Bar;

(aunque algunos compiladores emitirán una advertencia cuando hagas esto, asumiendo que probablemente no intentar hacer algo tan confuso y que, por lo tanto, se le debe pedir que verifique su código de nuevo).

y las siguientes expresiones se evalúan como verdaderas:

std::is_class<Foo>::value
std::is_class<Bar>::value

Tenga en cuenta, sin embargo, que no puede cambiar las palabras clave cuando redefiniendo; esto es solo porque (según la regla de una definición) las definiciones de clases duplicadas en las unidades de traducción deben "consiste 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.


90
2018-04-28 14:17



La única vez que uso una estructura en lugar de una clase es cuando declaro un funtor justo antes de usarlo en una llamada a 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()); 

50
2017-09-10 18:08



Desde el Preguntas frecuentes sobre C ++ Lite:

Los miembros y las clases base de una estructura son públicos de forma predeterminada, mientras que en clase, tienen el valor predeterminado en privado. Nota: debe hacer que sus clases base sean explícitamente públicas, privadas o protegidas, en lugar de confiar en los valores predeterminados.

struct y clase son funcionalmente equivalentes.

OK, suficiente de esa charla techno limpia y chillona. 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 poco encapsulamiento o funcionalidad. Una clase se siente como un miembro vivo y responsable de la sociedad con servicios inteligentes, una fuerte barrera de encapsulación y una interfaz bien definida. Dado 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.


30
2017-07-28 04:07



Un lugar donde una estructura ha sido útil para mí es cuando tengo un sistema que está recibiendo mensajes de formato fijo (por ejemplo, un puerto serie) de otro sistema. Puede convertir la secuencia 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, esta es la misma cosa que harías en C, pero creo que la sobrecarga de tener que decodificar el mensaje en una clase generalmente no vale la pena.


19
2017-09-10 16:43



Puede usar "struct" en C ++ si está escribiendo una biblioteca cuyas partes internas son C ++, pero la API puede llamarse mediante el código C o C ++. Simplemente crea un único encabezado que contiene estructuras y funciones API globales que expone a los códigos C y C ++ de esta manera:

// 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 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 cuando se mezclan C y C ++, pero este es un ejemplo simplificado.


15
2017-10-27 01:50



Estructura (PODs, de manera más general) son útiles cuando se proporciona una interfaz compatible con C con una implementación en C ++, ya que son portátiles a través de los bordes del idioma y los formatos del enlazador.

Si eso no te concierne, entonces supongo que el uso de la "estructura" en lugar de "clase" es un buen comunicador de intención (como 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 tiene la intención de 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 solo aprovechar el nivel de protección predeterminado de struct que es público ...


9
2017-09-10 17:46