Pregunta

¿En qué escenarios es mejor utilizar un struct contra un class en C++?

¿Fue útil?

Solución

diferencias entre un class y un struct en C++ son que las estructuras tienen por defecto public Los miembros, las bases y las 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 antiguas sin características similares a clases, y usar clases como estructuras de datos agregados con private datos y funciones miembro.

Otros consejos

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

  • struct por defecto es acceso público y class El valor predeterminado es el acceso privado.
  • Al heredar, struct por defecto es public herencia y class por defecto es private herencia.(Irónicamente, como ocurre con tantas cosas en C++, el valor predeterminado es al revés: public la herencia es, con diferencia, la opción más común, pero la gente rara vez declara structEs sólo para ahorrar en escribir "public" palabra clave.

Pero la verdadera diferencia en la práctica es entre una class/struct que declara un constructor/destructor y otro que no.Hay ciertas garantías para un tipo de POD de "datos antiguos", que ya no se aplican una vez que usted se hace cargo de la construcción de la clase.Para mantener clara esta distinción, muchas personas deliberadamente solo usan structs para tipos POD y, si van a agregar algún método, use classes.Por lo demás, la diferencia entre los dos fragmentos siguientes 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 de POD en C++?)

Hay muchos conceptos erróneos en las respuestas existentes.

Ambos class y struct declarar una clase.

Sí, es posible que tengas que reorganizar tus palabras clave de modificación de acceso dentro de la definición de clase, dependiendo de qué palabra clave usaste para declarar la clase.

Pero más allá de la sintaxis, solo La razón para elegir uno sobre el otro es la convención/estilo/preferencia.

A algunas personas les gusta seguir con el struct palabra 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 el class palabra clave para clases con funciones miembro y private datos, porque dice "clase" 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 dos clases siguientes son absolutamente equivalentes en todos los sentidos excepto en el nombre:

struct Foo
{
   int x;
};

class Bar
{
public:
   int x;
};

Incluso puedes cambiar las palabras clave al volver a declarar:

class Foo;
struct Bar;

(a pesar de esto rompe las compilaciones de Visual Studio debido a 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 cuando redefiniendo;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 "constan de la misma secuencia de fichas".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 en aras de la claridad.p.ej.:

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

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 la clase son privados de forma predeterminada.Nota:debes hacer que tus clases base sean explícitamente públicas, privadas o protegidas, en lugar de depender de los valores predeterminados.

Por lo demás, struct y class son funcionalmente equivalentes.

Bien, basta de esa charla tecno impecablemente limpia.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 encapsulación 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ías usar la palabra clave struct si tienes una clase que tiene muy pocos métodos y tiene datos públicos (¡tales cosas existen en sistemas bien diseñados!), pero de lo contrario probablemente deberías usar la clase palabra clave.

Un lugar donde una estructura me ha resultado ú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ías en C, pero encuentro que la sobrecarga de tener que decodificar el mensaje en una clase generalmente no vale la pena.

Puede usar "struct" en C++ si está escribiendo una biblioteca cuyas partes internas son C++ pero la API puede ser llamada mediante código C o C++.Simplemente crea un encabezado único 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 barra de funciones() en un archivo C++ usando código C++ y hacerla invocable desde C y los dos mundos pueden compartir datos a través de las estructuras declaradas.Por supuesto, existen otras advertencias al mezclar C y C++, pero este es un ejemplo simplificado.

Como todo el mundo dice, la única diferencia real es el acceso predeterminado.Pero uso particularmente 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;}
};

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 fronteras de idiomas y formatos de enlace.

Si eso no le preocupa, entonces supongo que el uso de "estructura" en lugar de "clase" es un buen comunicador de intenciones (como dijo @ZeroSignal anteriormente).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 por cable.

Las estructuras también son útiles para diversas tareas de metaprogramación, como plantillas de rasgos que simplemente exponen un montón de tipos de definición dependientes:

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

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

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.Por lo demás, en lo que al idioma se refiere, son equivalentes.

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

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 almacenamiento de datos.Le permitiré obtener algunas funciones auxiliares si facilita el trabajo con los datos.Sin embargo, tan pronto como los datos requieran control de flujo (es decir,getters/setters que mantienen o protegen un estado interno) o comienza a adquirir cualquier funcionalidad importante (básicamente más parecida a un objeto), se "actualizará" a una clase para comunicar mejor la intención.

Son prácticamente lo mismo.Gracias a la magia de C++, una estructura puede contener funciones, usar herencia, crearse usando "nuevo", etc., como una clase.

La única diferencia funcional es que una clase comienza con derechos de acceso privados, mientras que una estructura comienza con derechos de acceso públicos.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.

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

Nos saldrá un error: main_one is private porque no es accesible.Podemos resolverlo inicializándolo especificando es un público, es decir

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

Estructura.

Una estructura es una clase cuyos miembros son públicos de forma predeterminada.

struct test_one {
    int main_one;
};

Medio 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, es más fácil de esa manera.

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

Entonces, si solo quiero empaquetar información para moverme, uso una estructura, incluso si pongo 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.

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 a todos los miembros como constantes para evitar modificaciones por parte de otro código.

Una ventaja de struct encima class es 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 class inútil.

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

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

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 múltiples tipos simultáneamente uso 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 una estructura estudiante en los métodos get...() aquí - disfrútalo.

¿Cuándo elegiría usar estructura y cuándo usar la clase en C ++?

yo suelo struct cuando defino functors y POD.De lo contrario uso 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; }
};

Utilizo estructuras cuando necesito crear un tipo POD o funtor.

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 la estructura 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 agregar funciones miembro a la estructura.Aparte de estas diferencias, no encuentro nada sorprendente en ellas.

Como otros han señalado

  • ambos son equivalentes aparte de la visibilidad predeterminada
  • Puede haber motivos para verse obligado a utilizar uno u otro por cualquier motivo.

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

Utilice clase si la clase tiene una invariante;use struct si los miembros de datos pueden variar de forma independiente

Sin embargo, tenga en cuenta que no es prudente declarar algo hacia adelante.como una clase (class X;) y definirlo como estructura (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.

Utilizo struct solo cuando necesito contener algunos datos sin ninguna función miembro asociada (para operar con los datos del miembro) y acceder a las variables de datos directamente.

P.ej:Lectura/escritura de datos de archivos y flujos de sockets, 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 gran diferencia entre clase y estructura excepto la accesibilidad predeterminada.Además, depende del estilo de programación y de cómo lo utilices.

Pensé que Structs estaba pensado como una estructura de datos (como una matriz de información de tipos de datos múltiples) y las clases estaban diseñadas para el empaquetado de código (como colecciones de subrutinas y funciones).

:(

Nunca uso "estructura" en C++.

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

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

P.ej.

class PublicInputData {
    //data members
 };
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top