Списочные классы [TList, оператор dynamic_cast]

Списочные классы C++ Builder хранят указатели типа void*, которые могут адресовать любые объекты. Для того, чтобы воспользоваться таким указателем, необходимо выполнить преобразование типа. Преобразования можно выполнить двумя способами - статическим в стиле обычного C++ и динамическим (расширенным ANSI). Последний предпочтительнее по ряду причин. Почему станет понятно из примеров:

void __fastcall TForm1::Edit1Change(TObject *Sender)
{
TEdit* tmpedit=(TEdit*)Sender;
Label1->Caption=tmpedit->Text;
}

Данный код выполняет статическое преобразование из TObject к TEdit. Этот обработчик можно назначить сразу нескольким компонентам TEdit, но только TEdit! При попытке преобразования другого класса программа выдаст исключение на преобразование типов. На практике бывает часто необходимо выполнить преобразование из неизвестного класса. Конечно, можно поставить ловушки - инструкции try...catch, но проще воспользоваться динамическим преобразованием - оператором dynamic_cast. Вот пример его использования, аналогичный предыдущему:

void __fastcall TForm1::Edit1Change(TObject *Sender)
{
TEdit* tmpedit=dynamic_cast<TEdit*>(Sender);
if (tmpedit==NULL) return;
Label1->Caption=tmpedit->Text;
}

В угловых скобках указывается целевой класс, а в круглых - аргумент преобразования. При невозможности выполнить преобразование возвращается NULL. Исключение при этом не возникает.

После этого теоретического введения можно приступить к рассмотрению одного из представителей списочных классов VCL - класса TList. Вот его свойства и методы:

  • Capacity() - определяет емкость контейнера. Предпочтительнее заранее задавать емкость, чтобы каждый раз при вызове метода Add() не перераспределять память.
  • Count() - количество элементов.
  • Items[] - индексированный массив указателей на объекты списка. Нумерация с 0.
  • Add() - добавляет указатель-аргумент к списку.
  • Delete() - удаляет элемент по номеру.
  • Pack() - удаляет все указатели, равные NULL.
  • Move() - перемещение указателя.
  • Exchange() - обмен местами двух указателей.

Опять-таки приведу пример:

TList* list;
void __fastcall Button1Click(TObject* Sender)
{
const count=10;
list=new TList;
list->Capacity=count;
for (int i=0;i<count;i++)
{
TImage* img=new TImage(this);
img->Picture->LoadFromFile(IntToStr(i)+".bmp");
list->Add(img);
}
}

void __fastcall Button2Click(TObject* Sender)
{
Image1=dynamic_cast<TImage*>(list->Items[Edit1->Text->ToIntDef(0)]);
}

Этот пример создает список изображений и загружает их из файлов "0.bmp"..."9.bmp". Здесь показаны основные манипуляции.

Читайте также:
  • Класс TFileStream. Понятие потока VCL.
    Сначала я бы хотел бы дать некоторое вступление по поводу поточных классов VCL. Эти классы есть некоторое подобие альтернативы поточным классам C++. Как обычно в таких случаях с VCL, основной TStream класс никто впрямую не использует, от него можно только наследовать. Прямым потомком TStream явл...
  • Файловый ввод-вывод.
    fstream Инкапсулирует стандартный ввод-вывод. Я не буду рассматривать расширения этого класса под UNIX, ведь все равно программируем под Windows. Эти самые расширения касаются в основном прав доступа, по умолчанию 666 - allow all. В общем техника работы с этим классом такова. Сначала создается эк...
  • Таблицы откликов [MESSAGE_MAP, MESSAGE_HANDLER]
    В VCL определены некоторые стандартные события для компонентов. Можно заметить, что эти события похожи на стандартные сообщения Windows. Однако не все сообщения Windows можно найти в VCL, и не все сообщения VCL реализованы в WinAPI. Например, в WinAPI нет сообщения, аналогичному OnClick, с другой...
  • TRegistry
    Чтобы легче было разбираться с Хелпом, скажу, что понятие Key означает не параметр, как можно было подумать, а раздел. Каждый раздел является подразделом главного раздела, которые мы рассмотрели в предыдущем Шаге. Чтобы понятней было, скажу, что иерархия напоминает файловую систему, где HKEY_* - ...
  • Класс списка строк TStringList и его связь с INI-файлами [TStringList, TIniFile]
    Класс TStringList является потомком класса TStrings, используемого в некоторых компонентах VCL, оперирующих текстом. Однако для использования вне объектов класс TStrings не подходит, поскольку не имеет собственного конструктора. Для этих целей используется TStringList, расширяющий функциональнос...