Динамическое создание элементов на форме, динамические массивы
1. Можни ли на форме во время выполнения программы создавать и удалять элементы например создать 100 TEdit, после заполнения их пользователем счиать с них данные(желательно в цикле) и удалить?
2. Как организовать массив переменной длины к примеру из есть БД элементов, число которых сильно меняется(от 20 до 2000 000(в редких случаях)), естественно выделять все время память на 2000 000 не целесообразно.
Народ помогтите с такими вопросами:
1. Можни ли на форме во время выполнения программы создавать и удалять элементы например создать 100 TEdit, после заполнения их пользователем счиать с них данные(желательно в цикле) и удалить?
Тема динамического создания на форуме обсуждалоась не однократно. используй поиск.
Создается это так:
Edit->Parent = Form1;
//Дальше указываешь координаты и так далее
2. Как организовать массив переменной длины к примеру из есть БД элементов, число которых сильно меняется(от 20 до 2000 000(в редких случаях)), естественно выделять все время память на 2000 000 не целесообразно.
typedef vector<Element>ElementMassiv;
ElementMassiv Spisoc;
Допустим заполнеие
struct base{AnsiString name;
int nomber, age;
};
Далее нужно создать объект типа base в векторном виде
base b????;
И заполнить
b????=Edit1->Text;
С массивом разобрался спасибо. А со структурами что-то не получается.
Допустим заполнеие
struct base{AnsiString name;
int nomber, age;
};
Далее нужно создать объект типа base в векторном виде
base b????;
И заполнить
b????=Edit1->Text;
со структурами возможно будет полезен классический пример: самоадресуемые структуры:
struct base{
AnsiString name;
int nomber, age;
base * pr;
};
base *P0 = NULL, *Pnew, *Pold;
//выделяем память
Pnew = new base;
//запихиваем инфу
while(твое внешнее условие, сколько будет эдитов например)
{
Pnew->name=Edit1->Text;
if(P0 == NULL) P0 = Pnew;
else Pold->pr = Pnew;
Pold = Pnew;
}
Таким образом ты получишь цепочку структур, каждая из которых будет ссылаться на следующую через указатель pr, в этом деле самое главное не забыть самый первый указатель, через него можно по цепочке получить любой элемент любой из полученных структур, просмотр цепочки например можно сделать так:
Pnew = P0; //который мы запомнили, когда создавали цепочку
while (Pnew != NULL) //до последней структуры
{
ShowMessage("Имя: "+Pnew->name);
Pnew = Pnew->pr;//переход к следующей структуре
}
Повторюсь, пример классический, взято из "С++ Builder 6" А.Я.Архангельского.
С массивом разобрался спасибо. А со структурами что-то не получается.
Допустим заполнеие
struct base{AnsiString name;
int nomber, age;
};
Далее нужно создать объект типа base в векторном виде
base b????;
И заполнить
b????=Edit1->Text;
вопервых что такое векторный вид??? Ты в Corel что ли нарисовать его планируешь?:D
Если поместить в вектор -
VectorBase massivstruc;
base *b;
for(int i=0;i<Count_record;i++){
b->Name = Edit1->Text;
b->nomber = IntToStr(Edit2->Text);
b->age = IntToStr(Edit3->Text);
massivstruc.pop(b);
}
считать из вектора -
for(int i=0;i<massivstruc.count();i++){
b = massivstruc;
Edit1->Text=b->Name;
Edit2->Text=StrToInt(b->nomber);
Edit3->Text=StrToInt(b->age);
}
со структурами возможно будет полезен классический пример: самоадресуемые структуры:
Вообще-то это называется связанным списком.
Надо ли изобретать велосипед, если это уже сделали до тебя в различных вариантах и на более высоком профессиональном уровне?
Используй контейнеры из STL: list, vector, queue и т.п.
В контейнере можно хранить как сами объекты твоей структуры base (что предпочтительнее), так и указатели на созданные объекты.
std::list<base> baseList;
std::list<base*> basePtrList;
Как добавлять и удалять элементы посмотри любой справке по STL. Таковая есть, как отдельно (http://www.sgi.com/tech/stl/), так и в MSDN, думаю, что и в справке прилагаемой к CBuilder.
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
struct base{
int age;
base * pr;
};
base *P0 = NULL, *Pnew, *Pold;
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
int a;
//Определяем размеры структуры
a=StrToInt(Edit1->Text);
//Заполняем
Pnew = new base;
for(int i=0;i<=a;i++) {
Pnew->age=i;
if(P0 == NULL) P0 = Pnew;
else Pold->pr = Pnew;
Pold = Pnew;
}
//Выводим
while (Pnew != NULL)
{
ListBox1->Items->Add(Pnew->age);
Pnew = Pnew->pr;
}
}
//---------------------------------------------------------------------------
//==
struct base{
int age;
base * pr;
};
base *P0 = NULL, *Pnew, *Pold;
//==
Pnew = new base;
for(int i=0;i<=a;i++) {
Pnew->age=i;
if(P0 == NULL) P0 = Pnew;
else Pold->pr = Pnew;
Pold = Pnew;
}
//Выводим
while (Pnew != NULL)
{
ListBox1->Items->Add(Pnew->age);
Pnew = Pnew->pr;
}
}
//---------------------------------------------------------------------------
все просто ты создаешь всего навсего только один объект, а потом просто переприсваиваешь указатель, создавать объект надо в цикле ... это по поводу 2го вопроса,
а поводу 1го то ты просто зациклил список, а следовательно условие Pnew!=NULL будет всегда верным
Как понять следующую ситуацию: Сверяясь с Архангельским написал следующий тект. А он при выводе на экран виснет, и структура от начал до конца забита последним элементом.
....
//Выводим
while (Pnew != NULL)
{
ListBox1->Items->Add(Pnew->age);
Pnew = Pnew->pr;
}
}
//---------------------------------------------------------------------------
А чего понимать то - если ты уже решил (сверяясь с Архангельским...:D)писать свой список структур то необходимо позиционировать не только следующий но и предыдущий элемент списка + при создании элемента необходимо позиционировать его в списке, и создавать отделньно шаблон или класс для работы с списком структур и код должен выглядеть примерно так
int age;
base * _prev;
base *_next;
base():_prev(this),_next(this){}
~base(){}
next(){return _next;}
prev(){return _prev;}
base *insert(base *b){
base *c = _next;
b->_next =c;
b->_prev = this;
_next = b;
c->_prev = b;
return b;
}
};
...
template<class T>class ListBase:public base{
......
}
Шаблон можно не использовать - просто создать класс для работы с конкретным типом данных.
base():_prev(this),_next(this){}
~base(){}
И почему , если next prev функции они используются без скобок
next(){return _next;}
prev(){return _prev;}
base *insert(base *b){
base *c = _next;
b->_next =c;
b->_prev = this;
_next = b;
c->_prev = b;
return b;
}
};
PS Если вопросы слишком уж дурацкие посоветуй чего почитать.
Можешь объяснить что делает эта строка
base():_prev(this),_next(this){}
~base(){}
это конструктор который создает указатель на элемент списка и два указателя - на предыдущий и последующий элементы, пока элемент не помещен в список они оба указывают на текущий элемент.
Вторая строка - деструктор, в ней если нужно выполняются операции по очистке памяти.
И почему , если next prev функции они используются без скобок
next(){return _next;}
prev(){return _prev;}
base *insert(base *b){
base *c = _next;
b->_next =c;
b->_prev = this;
_next = b;
c->_prev = b;
return b;
}
};
next и prev - действительно функции и нужны что бы вернуть указатель на соответственно следующий и предыдущий элементы списка - _next и _prev - поля данных структуры, проще говоря указатель на следующий и предыдущий элементы они используются функциями типа вставить, добавить удалить и пр. Если бы это была не структура а класс (как в принципе и есть - пример взят из моего работающего кода), эти данные располагаются в закрытой области класса - а доступ через интерфейсные функции.
PS Если вопросы слишком уж дурацкие посоветуй чего почитать.
Если человек хочет чему-то научится - дурацких вопросов не бывает. Если хочешь реализовывать свои методы работы с данными - почитай руководства и документацию по STL, например "Стандартная библиотека С++ на примерах" Пабло Халперн'а, советую найти "Объектно-ореентированное программирование на Borland C++" Тэд Фейсон'а - это не Архангельский, я пользуюсь 4 изданием еще для версии 4.5, может есть новее.
Если можешь покажи рабочий исходник что бы хоть покопаться в нем, а то на теоретическом уровне ситуация слишком плачевная, буду искать книги которые посоветовал, кстати не подскажешь нет ли их в нете
Я могу выложить исходник полностью программы которая считывает объекты из бинарного файла помещает их в список - выполняет необходимые действия, распечатывает результат и записывает файл. Единственная проблема - комментариев очень не много...:D если подходит то можешь забрать отсюда http://malahov.dp.ua/pub/kot.rar, в архиве находится экзешник с делками и исходники, общий размер 4.5 метра приблизительно. Я правда не помню уже на чем остановился - но если будут проблемы какие - 136428914. Ну а если в инете что надо - так для этого поисковые сервера есть... :D
2. На malachov.dp.ua зайти не могу тем более дальше, если не трудно кинь на [email]brig@dtm.dp.ua[/email] (ограничение 5МВ)
3.Поисковиками пользоваться умею, но получается
без практических знаний трудновато (посмотрите на людей, которые с нуля пытаются читать Бьярна Cтрауструпа)кроме того множество книг на рынке по ООП С++ довольно разведенные (С++ - могучий, сильный прекрасный язык...или, когда я учился в школе мне очень нравилось программирование и я стал программистом и напсал эту книгу про мощный сильный прекрасный и т.п.) а на форумаx можно получить более менее приемлемую информацию, с которой уже остальные материалы становятся не такими заумными.
У меня небыло мыслей спамить cоde.net или мешать кому-нибудь поэтому если подобно происходит - скажите мне, я не буду задавать вопросы
1. уважаемому kot_'у большое спасибо, очень помог.
2. На malachov.dp.ua зайти не могу тем более дальше, если не трудно кинь на [email]brig@dtm.dp.ua[/email] (ограничение 5МВ)
3.Поисковиками пользоваться умею, но получается
без практических знаний трудновато (посмотрите на людей, которые с нуля пытаются читать Бьярна Cтрауструпа)кроме того множество книг на рынке по ООП С++ довольно разведенные (С++ - могучий, сильный прекрасный язык...или, когда я учился в школе мне очень нравилось программирование и я стал программистом и напсал эту книгу про мощный сильный прекрасный и т.п.) а на форумаx можно получить более менее приемлемую информацию, с которой уже остальные материалы становятся не такими заумными.
У меня небыло мыслей спамить cоde.net или мешать кому-нибудь поэтому если подобно происходит - скажите мне, я не буду задавать вопросы
Прошу прощения ссылка исправлена, запарился забыл поставить редирект с этого хоста:D
http://malahov.dp.ua/pub/kot.rar Все качается без проблем.
Вопросы задавать нужно - но не забывать просмотреть предыдущие темы тоже не мешает - многие вопросы обсуждались уже не однократно и по многу раз, в особенности это касается BDE - просто задать в поиске несколько вариантов поискового шаблона - и все необходимое найдется.:)
Понял, обещаю исправиться:). Такой ворпрос, а почему такая неприязнь к Архангельскому?
Причем здесь неприязнь? Книги Архангельского предназначены для получения начальных базовых навыков для работы с Borland C++ Bilder и в связи с этим рассмотрение сложных вопросов программирования просто осталась за рамками книги. Поэтому, если задачи стоящие перед вами выходят за рамки базовых - стоит учитывать, что ВСВ - это не отдельный язык программирования, а подмножество языка С++, и соответственно уметь использовать свойства этого языка. Архангельский касается этих вопросов весьма поверхностно. Почему - смотри выше. :)
Кстати файл закачался нормально?
Закачался прекрасно. Правда приложение сложноватое пока не очень разобрался
Если надо, могу выложить рабочую инсталляшку. Программа работает с накладными - там вего помоему пять или шесть классов.
struct base{AnsiString name;
int age;
}
base *b;
b=new base[количество элементов];
а дальше работать также как и с обычным массивом структур.
Правда возникла одна проблемка с БД если кто знает подскажите
Допустим в колонке БД field[0] заполнена числами , по размерам превышающим формат int, значит нужно испльзовать double, но как при этом присвоить ему значение конкретной ячейки
double i;
i=Table1->Fields->Fields[0]->AsInteger ; не сработает
Правда возникла одна проблемка с БД если кто знает подскажите
Допустим в колонке БД field[0] заполнена числами , по размерам превышающим формат int, значит нужно испльзовать double, но как при этом присвоить ему значение конкретной ячейки
double i;
i=Table1->Fields->Fields[0]->AsInteger ; не сработает
а использовать long?