2010-12-13 11 views
6

Los other topic y las respuestas no me hicieron esta pregunta:En C++, ¿por qué struct es, de hecho, clase?

¿Por qué C++ permite a struct se comportan igual que class? En un lado, C++ hizo compatible con C-struct haciendo a sus miembros pública por defecto (al igual que en C), mientras que por otro lado, se lo hizo ver como la clase por lo que le permite ser heredada de las clases, y la aplicación de otras técnicas orientadas a objetos (ya no tanto como C-struct). ¿Por qué no lo hizo simplemente viejo C-struct sin ningún OOP? ¿Alguna razón especial?

+7

Sus preguntas recientes sobre "¿Por qué C++, bla, bla ..." pueden ser respondidas por "¿Por qué no?". Me gusta que C++ lo haga de esta manera, y a las personas que desarrollaron el estándar también les gustó, es por eso que lo hicieron. – ybungalobill

+1

@ybungalobill: Hoy en día no solo estoy explorando la sintaxis/uso de C++, sino también la filosofía detrás de ellos. Es por eso que ves "Por qué C++, bla, bla ...". :-) – Nawaz

+6

, entonces tal vez debería leer "el diseño y la evolución de C++" –

Respuesta

6

Desde el punto de vista del lenguaje, estructuras y uniones son sólo tipos de clase. Hace la especificación del lenguaje más simple si hay menos conceptos (con una letra minúscula 'c') y también hace que el lenguaje sea menos propenso a errores, ya que es menos fácil omitir algo 'obvio' si cada propiedad común tuviera que explicarse para cada una de las estructuras , sindicatos y no la estructura, las clases no sindicalizados.

clases de C++ tienen una gran cantidad de funcionalidad potencial sobre las estructuras de C, sino como estructuras C pueden ser vistos como un degenerado clase C++, es más sencilla de permitir que sean exactamente esto. No hay ningún beneficio de tener un concepto especial estructura, así como un conceptoclase.

De ISO/IEC 14882: 2003, [clase] 9/4:

A estructura es una clase definida con la clave de clase struct; sus miembros y clases base son públicos por defecto. Una unión es una clase definida con la tecla clase union; sus miembros son públicos por defecto y solo tiene un miembro de datos a la vez.

+0

Me gustó esta publicación. +1 de mi parte – Nawaz

1

En C solo había estructuras para empezar. La orientación de los objetos comenzó cuando se diseñaron las bibliotecas cuando se pasaban punteros a esas estructuras a un conjunto de funciones de biblioteca que dependían de esa estructura. Un buen ejemplo es la API de Win32. No es una interfaz C++, es una interfaz C; pero todavía está orientado a objetos.

clases son casi las mismas que las estructuras de memoria se refiere. Las funciones miembro no se almacenan como parte de los datos del miembro de la clase. Es simplemente una estructura con punteros de funciones adicionales en el extremo. Por lo tanto, una tabla de funciones de clase se desreferencia de la misma forma que la API de Windows usa orientación de objeto, pero la encapsula para que no la vea.

Herencia, polimorfismo; ¿a quien le importa? Las personas estaban bien con C, y todavía haciendo bien con C.

+0

reglas de la escuela: me gustó esta publicación también. Buen post. :-) ¡+1 de mí! – Nawaz

+0

escuela: tenga en cuenta que los punteros de funciones adicionales (vtable) solo se necesitan cuando se trata de funciones virtuales. Las funciones de miembro "Normal" se resuelven estáticamente y no requieren memoria adicional. –

7

Permite estructuras existentes para montarse con el código C++ de una manera más natural. Por ejemplo, puede agregar funciones miembro a una estructura y heredar de una estructura, lo que no sería posible si las estructuras y las clases habitaran diferentes universos.

intención original era de BS para evitar una fractura de la comunidad entre el C-estilo tradicional campamento de "estructura", y la multitud OO "clase". También citó los beneficios de tener solo un concepto en lugar de dos.

+0

"Permite que las estructuras existentes se ajusten con el código C++ de una manera más natural. Por ejemplo, puede agregar funciones miembro a una estructura [...]" ... sí, esa es mi pregunta: por qué nos permite agregar miembro funciones? Tenemos clases para eso, ¿verdad? – Nawaz

+0

@Nawaz también permite agregar funciones miembro a las uniones. No podemos usar clases en lugar de sindicatos, para el propósito para el que se usan. –

+0

@ Johannes Schaub: En el caso de 'unión', tiene sentido, ya que "no podemos usar clases en lugar de uniones, para el propósito para el que se usan". Tiene mucho sentido. ¿Pero qué hay de struct? – Nawaz

1

Permitir que algo se declara como estructura para ser realmente una clase permite tipo de seguridad al crear una interfaz C.

Se puede declarar delante de su estructura para su interfaz de C:

struct Foo; 

Se puede declarar métodos en él

void doStuffThatModifiesFoo(struct Foo * foo, ...); 
struct Bar getStuffFromFoo(const struct Foo * foo); 

También puede escribir crear y destruir los métodos para ello.

Debajo de usted implementa Foo no como una estructura C sino como una clase, pero sus clientes C no necesitan saber eso. Esto es mejor que pasarlo por alto como un vacío * y luego lanzarlo (no es seguro si alguien te pasa un vacío * a un tipo completamente diferente y lo lanzas).

+1

Estrictamente hablando, esto no es una cosa de clase versus estructura. El mismo truco es posible en C. –

+0

puro. Sin embargo, sigue siendo útil cuando se implementa algo en C++, pero se necesita exponer la clase con sus funciones miembro como una estructura con función global. – Mephane

2
  1. se requiere por defecto "público" para los campos de struct para la compatibilidad con código C que puede acceder a los campos struct.
  2. se requiere por defecto "público" para la herencia estructura de modo que la clase hija podría ser utilizado en lugar de la estructura de base.
  3. Podría ser posible hacer struct en un tipo de datos diferente a clases (es decir, no permitir especificadores de tipo de acceso y métodos en ella), pero eso sería tanto inconveniente para la programación y añadir una gran cantidad de trabajo innecesario para el compilador desarrolladores .
+0

los primeros dos puntos son irrelevantes, creo que aquí, ya que no intenta responder mi pregunta. El tercer punto, la declaración de la segunda mitad no parece ser cierto. Ya hemos usado struct en C. ¡Así que usar c-struct simple no es para nada inconveniente! – Nawaz

+0

1-2 están ahí porque estas son las razones por las cuales se debe agregar una nueva palabra clave para la clase. Y por "inconveniente" me refiero a cambios incrementales. es decir, según usted, cuando quisiera proteger un campo de una estructura copiada y pegada del proyecto C, tendría que cambiarle el nombre a clase y declarar públicos a todos los demás miembros, y posiblemente reparar toda la herencia. – Shelwien

0

La cuestión de la "compatibilidad con C" solo tiene sentido en una dirección: el código C antiguo válido también debe compilarse como código C++. A la inversa, es imposible tan pronto como se utilice cualquier característica de idioma que solo tenga C++.

Eso significa que en C++, siempre se escriben clases, se puede omitir el uso de la palabra clave struct en absoluto; aunque algunos, incluyéndome a mí, piensan que son útiles para mostrar que una clase es simplemente una colección simple de valores con nombre, sin una encapsulación real o un comportamiento posiblemente complejo.

+0

Muchos guías de estilo modernos en C++ prefieren usar struct porque su valor predeterminado es public, por lo que primero se debe leer la interfaz pública. –

+0

@Fabio: Hmm, "many"? No creo que haya visto a nadie que las guías de estilo sugieran esto. Aunque tiendo a hacerlo cuando puedo hacerlo, por la razón que dijiste, pero no recuerdo haberlo recomendado en ningún otro lado. ¿Tienes un ejemplo? – jalf

+0

@jalf: No sé si lo han escrito en alguna parte, pero es bastante común en el código de impulso. LLVM parece usarlo solo para algunas partes (¿plantillas?). –