2011-01-24 10 views
7

struct es público por defecto, mientras que class es privado por defecto.¿Mato a un gatito cada vez que uso struct en todas partes en lugar de clase?

Tomemos Ogre3D por ejemplo; si cambio todas las ocurrencias class con struct, se compila (supongo) y el motor funciona igual que antes.

Si estoy en lo cierto, el código compilado es exactamente el mismo que antes, porque solo el compilador comprueba si se llama a un método privado/protegido, no se comprueba en el tiempo de ejecución.

Si todavía estoy bien, class es sólo una palabra clave que sólo hace que sus ojos lindos y pidiendo "por favor encapsular los datos: se ahorrará un gatito", mientras que los ámbitos privados/protegidas están todavía en manos del usuario.

Sé que suena un poco escaso o irrelevante rebelde (algo así como "C es tio KISS, do not go"

Volver a la pregunta: ¿qué hace la norma dicen sobre esta pequeña diferencia entre struct y class mientras ¿Generar código de máquina? ¿Por qué agregar una palabra clave y tratar de impresionar a los programadores con el llamado "modelo OO" mientras no se aplica? ¿Fue influenciado por Java?

+6

Todo lo contrario en realidad. Matas a un gatito cada vez que usas la palabra clave 'clase' donde 'struct' sería suficiente. No, no fue influenciado por Java ya que C++ fue el primero. –

+1

C++ no es estrictamente un lenguaje OO, es un lenguaje multi-paradigma que admite más que solo OO, por lo que no busca aplicar los conceptos de OO en el desarrollador. Depende del desarrollador usar el estilo OO si así lo desean. Consulte la entrada de información de la etiqueta C++ aquí http://stackoverflow.com/tags/c%2b%2b/info – Glen

+0

Hay más respuestas a esta pregunta en http://stackoverflow.com/questions/4090794/c-when-should -i-use-structs-instead-of-classes-and-where-are-the-speed-differe. –

Respuesta

2

La diferencia entre struct y class es sólo el nivel de acceso por defecto de las bases y atributos, y los niveles de acceso se verifican sólo en tiempo de compilación, por lo que podría tener la tentación de obtener alguna biblioteca editar los encabezados y cambiar todo class con struct para obtener acceso a los detalles internos.

No

compiladores no están obligados a generar exactamente el mismo código si cambia el especificador de acceso por defecto. En particular, estas dos clases podrían o no tener el mismo diseño de memoria, dependiendo del compilador:

struct a { 
    int a; 
private: 
    int b: 
}; 
class b { 
    int a; 
public: 
    int b; 
}; 

La razón es que la norma requiere que todos los atributos miembros que serán expuestos en la memoria en el aumento de las posiciones dentro de la misma clasificación para el acceso . Los compiladores están permitidos (no conozco ninguno que sí lo haga, pero como esto no es un requisito, puede cambiar en la próxima versión), para reordenar los campos desde diferentes bloques de acceso. Un compilador podría decidir que los atributos públicos son los primeros, mientras que los privados aparecen al final del objeto, y eso significaría que la posición de los campos a y b en las dos clases se intercambiaría.

+0

Me he encontrado con este error, aunque no porque cambié class to struct o viceversa. Estamos realmente estandarizados en struct. Lo que hice fue exponer una sola función y luego me olvidé de actualizar la .lib para uno de mis módulos. Afortunadamente, la condición resultante no fue posible en lugar de resultar en algo raro. comportamiento. –

+0

Creo que confiar en un diseño de memoria específico generalmente es una idea peor que buscar en el código para sustituir la clase por clase o viceversa. – wilhelmtell

+0

@wilhelmtell: Estoy de acuerdo, pero a veces no lo noto. En particular, con el Por ejemplo, si toma una biblioteca (la pregunta se refiere a Ogre3D) que está precompilada y modifica los encabezados para obtener acceso a los miembros privados, entonces su código y el código de la biblioteca nk hablan del mismo objeto, pero cuando se refieren a un miembro hacen referencia a diferentes bits en el objeto (e incluso posiblemente objetos de diferentes tamaños si los requisitos de alineación no se cumplen en el nuevo diseño). No es obvio que confíe en el diseño de la memoria, pero lo hace cada vez que compila. –

2

No hay otras diferencias que el acceso predeterminado. En realidad, incluso puede escribir algo como:

class X; 

X* pX; 

struct X {}; 

Y debe compilarse.

+0

MSVC dará un buen paso. –

1

La única diferencia entre structs y clases en C++ es que las clases tienen miembros privados y clases base de forma predeterminada. Normalmente, el cambio de class a struct no debe afectar el código de máquina generado.

+0

"Clases base por defecto"? ¿Qué quieres decir? Las estructuras pueden tener una base, al igual que las clases, pero debe especificar explícitamente la base (s) en cualquier caso. –

+1

@Seva Alekseyev: me refiero a que las clases tienen "clases base privadas por defecto" (el acceso predeterminado se aplica tanto a los miembros como a las clases base). – vitaut

4

En realidad, class y struct se comprueban en tiempo de compilación. La única diferencia es si el valor predeterminado para los miembros para los que no ha especificado explícitamente el acceso es public (para struct) o private (para class). De lo contrario, producen exactamente los mismos objetos. Si especifica todo su control de acceso explícitamente, puede usar cualquiera de ellos y serán los mismos.

+0

No hay garantía de que generen el mismo código. En particular, se garantiza que el diseño de los miembros de datos de una clase tiene direcciones de memoria crecientes solo dentro del mismo bloque. Una clase con todos los miembros públicos o todos los miembros privados tendrá el mismo diseño, pero un compilador conforme podría decidir colocar a todos los miembros públicos (en orden) antes de cualquier miembro privado, independientemente de dónde se encuentren en la definición de clase. En tal compilador, cambiar 'clase' por' struct' rompería el sistema. –

+0

@David - ¿Estás seguro? ¿No son estas reglas las mismas para una estructura? Esto es completamente nuevo para mí.¿Alguna referencia? – Tomas

+0

Son los mismos para clase o estructura, la única diferencia es el especificador de acceso predeterminado, pero no hay garantía de que: 'struct a {int x; protected: int y; }; 'y' clase b {int x; protected: int y; }; 'tendrá el mismo diseño. La referencia sería en §9.2/12 "Los datos no estáticos miembros de una clase (no unión) declarada sin un intermediario de acceso intermedio se asignan de modo que los miembros posteriores tengan direcciones más altas dentro de un objeto de clase. El orden de asignación de los miembros de datos no estáticos separado por un especificador de acceso no especificado (11.1). " –

5

La norma no dice nada sobre la generación de códigos de máquina en absoluto.

struct se ha conservado para facilitar la migración del código C heredado. Normalmente, los programadores de C++ lo usan para estructuras similares a POD.

+1

¿Por qué el voto a favor? –

+1

Correcto. Solo tiendo a usar 'struct' casi siempre. Solo uso 'clase' si tengo miembros' privados' o 'protegidos' y no miembros públicos que no sean los miembros generados o heredados del compilador. Esto porque me gusta ubicar a mis miembros privados en la parte inferior, porque son los menos interesantes en la interfaz de una clase. – wilhelmtell

2

No. La diferencia entre struct y class se limita a la accesibilidad predeterminada de sus miembros y herencia. Ambos son public para struct y private para class

1

No, definitivamente no fue influenciado por Java. Verifica la línea de tiempo. :)

Incluso si no hace más que controlar la visibilidad predeterminada, eso sigue siendo bastante significativo. De alguna manera se convierte en una cuestión de tener la semántica disponible que te permita decir lo que quieres decir.La idea de que, si está usando struct, entonces probablemente esté trabajando dentro de un paradigma anterior donde la visibilidad pública es la única que normalmente se consideraría, y si está usando class, está pensando en más OO términos en los que la visibilidad privada se tiene en mayor estima. No lo sé, tiene sentido para mí, amigo.

-1

struct existe por razones heredadas y eso es todo. No mata a un gatito ni a nada cada vez que usa struct en lugar de class o viceversa, son lo mismo, de manera realista, con una palabra clave ligeramente diferente y predeterminada.

0

Hmm, ahora ... Si alguna vez se pone un programa de este tipo en el espacio público, decir algo como OSS, la gente va a tirar piedras a usted;)

La palabra clave struct es una especie de herencia C. Y sí, la única diferencia (por lo que recuerdo) es el comportamiento predeterminado con respecto a los miembros que están siendo protegidos.

Bjarne Stroustrup en "The C++ Programming Language":

Por definición, una estructura es una clase en la que los miembros son de público predeterminado; es decir

struct s {...

es simplemente la abreviatura de

clase s {public: ...

Pero el modelo OO es, con mucho, más que la encapsulación. Agrega cosas como herencia y funciones de miembro.

+1

Las estructuras pueden tener funciones de herencia y miembros. :) –

+0

Sí, eso es lo que digo :) Acabo de mencionar esto, debido a la última frase de gokoon: "¿Por qué agregar una palabra clave y tratar de impresionar a los programadores con el llamado" modelo OO "mientras que no se aplica entonces?" Solo mencionar que ese modelo OO es más que una encapsulación (Pero tienes razón, ahora que lo leí de nuevo, suena un poco como que solo "clase" implementaría esto. –

1

Hay personas que intentan usar la palabra clave 'struct' para significar varias cosas. Por ejemplo, algunas personas intentan usar struct para especificar POD-ness o para ser solo clases de datos (clases con solo variables de miembro público y sin funciones).

En mi opinión, este es un grave error y todos los motivos que he escuchado son defectuosos. Por un lado, una palabra clave como struct no es suficiente para expresar las condiciones que intentan usar para documentar.Dado que la palabra clave en realidad no significa nada en particular, la gente lo acepta o intenta afirmar su propia idea de lo que debería significar. Hay demasiadas opiniones incompatibles sobre qué structsignifica en el código para que documente cualquiera de ellas. Desea documentar cosas como, "Este objeto siempre debe ser un POD", lo más claramente posible en lugar de confiar en los detalles estándar del equipo oscuro que pueden ser difíciles de recordar. Entonces, para documentar tal cosa, la única cosa suficiente, honestamente, es // This object must always be a POD. Es claro, simple, y no puede ser malinterpretado por alguien que sepa lo que es un POD, y esto está bien definido.

El mejor argumento que he escuchado para usar la palabra clave class en lugar de struct es que debe preferir el acceso privado al acceso público, revelando solo lo que es necesario. En otras palabras, el tipo de herencia "por defecto" y la exposición de acceso deben ser privados hasta que se demuestre que es necesario un mayor acceso. Estoy de acuerdo con esta opinión, pero no estoy de acuerdo en que sea necesario utilizar la palabra clave struct para cumplir con este principio.

Lo que uno decida va a ser bastante arbitrario. Las razones más adelante se pueden afirmar para la decisión, pero creo que las personas que han elegido uno u otro no son fáciles de convencer. Cambié de 'clase' a 'estructura' porque leo demasiados libros sobre C++ moderno y demasiado código de refuerzo; rara vez verá la palabra clave 'clase' en ninguno de los dos. La verdad sea dicha, no importa; sigue los estándares del equipo en el que te encuentras en ese momento. En mi opinión, agregar una palabra clave que esencialmente no tiene sentido fue un error.

Editar: Aunque, tengo que decir que otra razón por la que no me gusta usar class es que significa demasiadas cosas, aunque también significa nada en particular. Por ejemplo, puede usar class en lugar de typename en las especificaciones de parámetros de la plantilla. Incluso si usa la palabra clave class puede pasar cualquier tipo y no necesariamente cualquier tipo de clase (como int). La única vez que me gusta usar la palabra clave class es donde realmente significa algo y donde realmente tiene que hacerlo: especificando los parámetros de plantilla de plantilla.

Cuestiones relacionadas