PDA

Ver la Versión Completa : Es posible crear un array de TCheckBox?


Negriz
18-04-2009, 08:39:05
Hola!!!
quiero hacer un vector de CheckBox en tiempo de ejecucion, hasta ahora conozco que para crear un checkbox en este estado debo seguir estos pasos:
1) Creo un puntero de tipo CheckBox
TCheckBox *test = new TCheckBox(this);
2) Hago visible el objeto
test->Visible = true;
3) le doy coordenadas
test->Left = 5;
4) lo inserto en el form (la verdad no se como funciona esto muy bien, solo que recive un tipo de dato TControl)
InsertControl(test);

buen con eso creo CheckBox en tiempo de ejecucion, pero cuando quiero crear un vector(array) se me complica la cosa...

usé algo como esto:

//para crear un vector(array) de enteros:
int vector* = new int[posiciones];
//pero en este caso:
TCheckBox *test = new TCheckBox[posiciones];
//esto no funciona, me dice que no puede encontrar el constructor mensionado,
//debe de ser por que hay que inicializar el contructor del TCheckBox con un puntero.

Tambien probe usando la libreira vector:

#include <vector>
using namespace std;
vector <TCheckBox> test;
test.resize(10);
test[0].Visible = true;
test[0].Left = 5;
InsertControl(test[1]);
//aca me bota error por que estoy manadando un puntero y no un TControl
//asi que lo use de este modo:
InsertControl(&test[1]);
//pero me muestra un error y se va a la libreira vector...


Bueno mi idea es crear un Array de CheckBox, alguna sugerencia...

Muhcas gracias.

escafandra
19-04-2009, 01:42:41
Hola, Negriz.

El problema de los punteros en C crea algún quebradero de cabeza a más de uno. Los punteros son una herramienta muy poderosa a la par que peligrosa para la estabilidad de un programa, de forma que es muy conveniente entenderlos bien. Si sabemos usarlos, nos proporcionarán muchas satisfacciones. Voy a tratar de resumir y explicar los aspectos más importantes para este caso particular.

1. El primer concepto a tener presente: Un puntero representa la dirección de memoria de lo que apunta, y el tipo del puntero es el tipo del objeto o variable apuntada.

2. Podemos tener punteros a cualquier cosa, incluidos punteros a punteros.

3. Un array, se representa por un puntero al primer elemento, y podemos tener arrays de cualquier cosa y representarlo por un puntero.

4. Podemos aplicar la aritmética de punteros. Si sumamos un entero a un puntero, obtenemos un puntero al siguiente elemento del array que representa ese puntero. La resta funciona igual. La aritmética es sensible al tipo de puntero, como es lógico.

5. El índice de un array aplicado al puntero devuelve el elemento indexado. Con la aritmética de punteros, la suma del indice al puntero, es un puntero a ese elemento indexado, pero no el propio elemento, que será el valor del puntero. De esta manera esto es cierto: vector[i] == *(vector+i)

En tu caso, para definir un array de TCheckBox, tienes que tener en cuenta que un objeto de ese tipo es realmente un puntero, por eso lo tienes que crear con el operador new. Es decir, no tienes un objeto sino en realidad un puntero a dicho objeto. Para crear un array de cualquier objeto de las clases VCL, lo que en realidad necesitas es un array de punteros de dicho tipo.

Si int i es un entero, int *pi = &i es un puntero a un entero que es i. int **ppi = pi es un puntero a un puntero entero.

Si TCheckBox *test es un puntero a un TCheckBox, TCheckBox **Arraytest es un puntero a un puntero de tipo TCheckBox, o lo que es lo mismo, puede estar representando un array de punteros TCheckBox, que es lo que tu quieres. Ahora sólo tienes que reservar la memoria necesaria para el array de punteros y para esos punteros.

Dejémomos de royos y vamos al grano:


// Crear el Array de TCheckBox
int Count = 10;
// reservo espacio para 10 punteros del tipo TCheckBox*
TCheckBox **ArrayCB = new TCheckBox*[Count];

// Creo los elementos del array y damos los valores necesarios...
for(int i=0; i<Count; i++){
ArrayCB[i] = new TCheckBox(this);
ArrayCB[i]->Left = 5;
ArrayCB[i]->Top = 25+(25*i);
ArrayCB[i]->Caption = "TCheckBox " + IntToStr(i);
InsertControl(ArrayCB[i]);
}
Y, por supuesto, en algún momento habrá que destruirlo:


// Destruir el Array
// Destruyo los elementos
for(int i=0; i<Count; i++){
delete ArrayCB[i];
}

// Destruyo el Array de punteros
delete [] ArrayCB;
Espero haber sido claro y poco aburrido.

Saludos. :cool:

PD. No te comenté que std::vector es un template que crea clases para dar funcionalidad a arrays. En el fondo es lo mismo que te esplique, pero con la facilidad de que una clase se encarga del trabajo de crear el array, reservar memoria, destruir, redimensionar el array.... Antes de usar esta facilidad conviene entender los fundamentos.

Neftali [Germán.Estévez]
20-04-2009, 09:30:07
Bueno mi idea es crear un Array de CheckBox, alguna sugerencia...

Podrías revisar TObjectList, que está para cosas como estas.

escafandra
20-04-2009, 22:27:48
Negriz, Neftali te aconseja bien. En el entorno VCL esa (http://www.clubdelphi.com/foros/showpost.php?p=345508&postcount=3) es a opción mas fácil, pero la vía que elegiste es más genérica y puede usarse para cualquier array, sea de componentes o de cualquier cosa. Así entendí que pretendías hacerlo. En cualquier caso, resuelvas como resuelvas aprende y entiende la vía de los punteros. ;)

Saludos.

Negriz
22-04-2009, 16:45:37
jejeje al parecer, no se por que pero el destino quiere que yo aprenda a pregramar :D, ahora que tengo algo mas de tiempo libre jejeje mi PC empezo a fallar me dice..."El sistema no se ha podido iniciar debido a que falta o no se encuanta C:/windws/config/sysem... bla bla bla" logro repararlo pero cuando apago el pc, sale lo mismo :( :o

Ahora si, regresando al tema de programacion, primero agradecer por los comentarios :)

Podrías revisar TObjectList, que está para cosas como estas.

[/B]Neftali[/B] la verdad no habia pensado en eso, no lo he usado antes, por que el lugar donde estudio C++ Builder es en el clubdelphi, asi que trato de aprender lo que mas pueda :) solo por alimentar mi curiosidad, eso es todo y tume acabas de dar algo nuevo para aprender a usar, boy a buscar como usarlo para no hacer malas preguntas... muhcas gracias.

[/B]escafandra[/B] la verdad si queria hacerlo con punteros, ya que hace algun tiempo estube trabajando con ellos en la universidad cuando me enseñaron el Dev C++ pero no lo recordaba muy bien, ademas nunca me mostraron:
TCheckBox **ArrayCB = new TCheckBox*[Count];


haber si lo entendi, pongo dos asteriscos por que es un array de punteros?
si es asi ya entendi, por que claro, yo no lo podia hacer por que mis objetos en el vector no eran punteros:

ArrayCB[i] = new TCheckBox(this);

jejeje por eso me decia que no podia usar el this ayi :P.

Muchas gracias, esto es realmente nuevo para mi, como dije boy a buscar mas sobre el ObjectList para poder hacerlo de varias maneras :D :D
U saludo.

escafandra
22-04-2009, 17:01:02
haber si lo entendi, pongo dos asteriscos por que es un array de punteros?

Exactamente. Dos asteriscos significan que defines un puntero a un puntero. Eso puede ser un array de punteros. Tres asteriscos significan un puntero a un puntero que apunta a otro puntero, o un array de arrays........je je la cosa se complica.... :rolleyes:

Pero los punteros no tienen porqué ser arrays, con ellos puedes hacer lo que quieras, buffers, castings, interpretaciones, movimientos de memoria, programación a bajo nivel...;)

Saludos.