2011-01-04 16 views
8

Me confunde. Lo mejor que pude encontrar fue leer el tutorial de cplusplus.com y todo lo que tienen que decir sobre punteros a clases.Cuándo utilizar el puntero a una clase y cuándo simplemente crear una instancia como una variable

"es perfectamente válida para crear punteros que apuntan a clases. Simplemente tenemos que tener en cuenta que una vez declarada, una clase se convierte en un tipo válido, por lo que podemos utilizar el nombre de clase como el tipo para el puntero"

Lo cual no me dice nada acerca de cuándo usarlos sobre la instanciación normal. He visto el operador -> muchas veces y he visto algunos códigos, pero no puedo descifrar por qué lo hicieron.

Se apreciarán los ejemplos genéricos; pero más específicamente relacionado con la programación de GUI. Es donde lo encontré primero.

QGridLayout *mainLayout = new QGridLayout; 
mainLayout->addWidget(nameLabel, 0, 0); 
mainLayout->addWidget(nameLine, 0, 1); 
mainLayout->addWidget(addressLabel, 1, 0, Qt::AlignTop); 
mainLayout->addWidget(addressText, 1, 1); 

Por qué no

QGridLayout mainLayout 
mainLayout.addWidget 
... 

(Es imposible compilar si cambio el código de ejemplo a eso y probar, pero usted consigue el punto)

Gracias de antemano

+0

Posibles duplicados: http://stackoverflow.com/questions/4029970/c-what-are-scenarios-where-using-pointers-is-a-good-ideatm-closed http://stackoverflow.com/questions/2144698/common-uses-for-pointers –

+1

Asegúrese de no cometer el error de pensar "Qt hace las cosas de esta manera, por lo que C++ hace las cosas de esta manera". Creo que a muchas personas, incluido yo, no les gusta la forma en que Qt hace muchas cosas, y la gestión de la memoria es una de ellas. Pero cuando está en Roma ... – GManNickG

+0

Los apuntadores no apuntan a las clases. Los punteros apuntan a los objetos. –

Respuesta

9

Un buen La forma de pensar cuándo apilar-asignar (no puntero) versus asignación de pila (puntero) un objeto es pensar cuánto tiempo quiere que ese objeto viva. Si coloca el objeto en la pila como una variable local, se limpiará y dejará de existir tan pronto como la función regrese. Si desea que el objeto sobreviva a la llamada de función que lo creó, colóquelo en el montón.

Con el ejemplo del diseño de la cuadrícula, creo que la versión del puntero es más apropiada porque después de que la llamada de función que crea el diseño retorna, usted todavía desea tener el diseño por ahí. De lo contrario, el diseño solo existiría mientras se ejecutara la función.

+0

El montón y la pila son términos obsoletos, confusos e inexactos para la duración de almacenamiento. Los objetos con duración de almacenamiento automática se destruyen automáticamente cuando sale el bloque en el que se crearon. Los objetos con una duración de almacenamiento dinámico se crean con una nueva expresión, y su duración dura hasta que se destruyen mediante una expresión de eliminación. Puede obtener un puntero a cualquier tipo de objeto. –

2

Una buena razón es polymorphism y envío dinámico. Al tener un puntero declarado a un tipo de clase base y asignarlo a una instancia de un subtipo, podría estar invocando versiones diferentes del método. En los ejemplos anteriores, probablemente haya algún tipo de base (¿QTLayout?) Con el que se puede declarar el puntero.

Otra razón es una situación en la que desea que su objeto "viva" más allá del alcance del método en el que se declara. Su segundo ejemplo se asigna en la pila y se desasignará cuando se vaya.

0

¿QGridLayout es una clase? El segundo debería funcionar bien si arreglaste los errores tipográficos. Usted dijo que no compila. ¿Deberíamos adivinar el error?

Crear el objeto como una instancia local está bien. El único problema potencial es si la clase es grande, ya que esto tiende a agotar excesivamente el espacio de la pila.

Tenga en cuenta que un objeto puede asignar toda la memoria que necesita y que no afectará su tamaño en la pila.

1

La verdadera pregunta no es sobre el uso de punteros, sino sobre la asignación dinámica. La asignación dinámica de un objeto (con new) le permite controlar el lifetime del objeto. Si desea crear el objeto en una función pero no desea que deje de existir tan pronto como la función finalice, la asignación dinámica es para usted.

Por lo general, verá punteros que apuntan a objetos asignados dinámicamente (ya que esta es la mejor manera de tratar con ellos, las referencias son una alternativa torpe); sin embargo, puede tener un puntero a un objeto con una duración de almacenamiento automático también:

QGridLayout mainLayout; 
QGridLayout* ptr = &mainLayout; 
ptr->addWidget(nameLabel, 0, 0); 
ptr->addWidget(nameLine, 0, 1); 
ptr->addWidget(addressLabel, 1, 0, Qt::AlignTop); 
ptr->addWidget(addressText, 1, 1); 

^En este ejemplo, estoy usando el almacenamiento automático (mediante la creación del objeto como una "variable normal" como usted dice) , por lo que el objeto se destruirá al final del alcance del bloque adjunto (probablemente el final de la función, o tal vez de un bloque condicional (if)), pero aún usando un puntero con él.

Espero que ayude un poco.

0

Emplear un ptr a una clase frente a la instanciación en la pila también permite la existencia condicional del objeto, es decir, el valor NULL, si lo necesita como un caso manejado.

Cuestiones relacionadas