<< Предыдущая страница

1.3.2 C++Builder и Delphi

Все компоненты, формы и модули данных, которые накопили программисты, работающие в Delphi, могут быть повторно использованы в приложениях C++Builder для Windows без каких бы то ни было изменении. Delphi пока еще продолжает оставаться самой легкой в использовании и самой продуктивной системой RAD. Поэтому C++Builder идеально подойдет тем разработчикам, которые предпочитают выразительную мощность языка C++, однако хотят сохранить продуктивность Delphi. Уникальная взаимосвязь этих систем программирования позволяет при создании приложения без труда переходить из одной среды разработки в другую.

Политика, проводимая руководством отделов математического обеспечения большинства фирм и организаций, допускает свободу разработчиков в выборе языка программирования, при условии совместимости производимых ими объектов и кодов. Неукоснительно следуя этой политике, C++Builder сохраняет материальные вложения в Delphi, вобрав в себя Библиотеку Визуальных Компонент, интуитивную интегрированную среду, визуальные механизмы двунаправленной разработки, методику наследования форм и разномасштабные средства доступа к базам данных.

Гамлетовская проблема выбора между двумя альтернативами вообще не ставится - в мире программистов достаточно жизненного пространства для "мирного сосуществования" обеих систем. Оставьте ненужные споры политического толка о преимуществе одной системы над другой. Используйте тот аппарат программирования, который сделает решение ваших задач более продуктивным, который вам больше нравится и который вам представляется более выразительным. C++ и Delphi равноправны в вашей работе - почти все, что вы написали в Delphi, можно легко использовать в C++Builder, и наоборот. Не забывайте об основном направлении своей профессиональной деятельности - создании качественных и надежных программ под операционную систему Windows.

Преимущества разделения кода между C++Builder и Delphi:

• Программисты могут работать в той среде, которая лучше и быстрее обеспечит реализацию поставленной текущей задачи. Delphi и C++Builder скомпилируют и соберут готовое приложение с одинаковым успехом.

• Написав некоторый объект для проекта Delphi, вы сможете повторно использовать его, без изменений, в проекте C++Builder.

• Delphi предлагает программистам очень простой, легкий в освоении синтаксис языка. Ваше начальство может не опасаться, что разработки Delphi не пойдут на C++Builder. При реализации сложных проектов большой командой программистов любой ее участник волен выбрать язык Объектный Паскаль или C++ в соответствии с индивидуальным вкусом, навыками и приверженностью. В любых комбинациях результатом совместной разработки будет единая высокоэффективная исполняемая программа.

• Выбирайте Delphi, когда вам надо как можно скорее создать какой-нибудь простой модуль или объект, даже если вы привыкли работать на C++.

Таким образом, C++Builder в симбиозе с Delphi образует исключительно продуктивную пару систем для быстрой коллективной разработки сложнейших приложений для Windows.

1.3.2.1 Какую систему выбрать?

Для тех, кто впервые остановился на перепутье, неизменным ответом на этот сакраментальный вопрос будет: "Смотря для чего".

Вы должны знать (если уже не знаете), что Delphi использует язык Объектный Паскаль, который преподается во многих специализированных школах и учебных институтах. Если вы только начинаете пробовать свои силы в программировании для Windows, лучше, видимо, выбрать Delphi. Придуманный Н.Виртом как средство для обучения студентов программированию, язык Паскаль стараниями специалистов корпорации Borland видоизменился в Объектный Паскаль для Windows и стал основой мощной профессиональной системы, которой по силам любые задачи - от создания простых вычислительных программ, до разработки сложнейших реляционных СУБД.

C++Builder, как следует из названия, построен на языке C++, который наиболее распространен в крупных фирмах, занимающихся разработкой математического обеспечения профессионального уровня. Если вы обладаете определенными познаниями в языке C++ и программирование должно стать, или уже является, вашей основной специальностью - выбирайте C++Builder. Не излишне заметить, что на западном рынке профессиональные C++ разработки пользуются гораздо большим спросом, нежели продукты системы Delphi, да и оплачиваются C++ программисты несколько выше, чем "паскальщики".

Современные программисты, как правило, владеют по меньшей мере одним из этих языков. Если вы уже работаете в среде Delphi, переход на C++Builder не покажется слишком болезненным, и наоборот. Обе системы находятся на примерно одинаковом уровне популярности среди потребителей. Обе системы построены на идентичном фундаменте - Библиотеке Визуальных Компонент.

1.3.2.2 Какая система является более мощной?

"Конечно C++Builder" - вот моя первая реакция на подобный вопрос. Однако, хорошо известно, что опытные разработчики способны справиться с поставленной задачей на Паскале лучше, чем большинство рядовых C++ программистов. Я знаком с несколькими настоящими мастерами программирования на Паскале и могу сказать, что в их руках этот инструмент способен производить удивительно красивые, эффективные и надежные творения. Если вы намерены специализироваться в области разработки компонент для VCL, используйте более удобные и гибкие средства Delphi, хотя созданные вами компоненты предназначены для внедрения в обе системы.

Для большинства рядовых пользователей обе системы покажутся поначалу (и надолго будут считаться) одинаково мощными.

1.3.2.3 Как использовать код Delphi в C++Builder

C++Builder не делает различия между тем, какие программные модули вы добавляете к проекту своего приложения - написаны они на C++ (файлы с расширением СРР) или на Delphi (файлы с расширением PAS). Компилятор свободно принимает следующие кодовые конструкции модулей Delphi 2.0: компоненты,формы, объекты, константы, простые методы и функции - все перечисленные коды можно прямо подставлять в свои проектные файлы. Технология визуального наследования форм дает возможность модифицировать формы Delphi в среде C++Builder без каких бы то ни было проблем.

Опытным программистам откроются следующие возможности системы C++Builder:

• Подгружать к проекту динамические библиотеки Delphi (файлы с расширением DLL). Разделение кода с помощью динамически подгружаемых DLL особенно целесообразно при ограниченном объеме оперативной памяти.

• Использовать OLE объекты Delphi и компоненты ActiveX. Связь OLE объектов позволяет разделять код не только с Borland C++Builder, но и с программными комплексами производства других фирм (Microsoft Word, Excel или Visual Basic).

• Разделять с Delphi общие объекты посредством унифицированных Таблиц Виртуальных Методов (VMTs).

1.3.2.4 Как использовать код C++Builder в Delphi

В C++ разрешен ряд синтаксических конструкций (таких как множественное наследование и перегрузка функций), которые делают невозможным прямой перенос кода C++Builder в проект для Delphi. Однако, существуют следующие обходные пути:

• Компоновать СОМ объекты, написанные на C++, которые поддерживают типизированные библиотеки - все необходимые для сборки проекта приложения файлы Delphi 97 генерирует автоматически из соответствующих библиотек.

• Любая функция, написанная на C++ и помещенная в DLL, может быть прямо вызвана из Delphi - Delphi поддерживает все общие спецификаторы вызова функций CDECL, PASCAL и STDCALL.

• Обращаться к объектам, написанным на C++, из Delphi посредством упомянутых Таблиц Виртуальных Методов.

В принципе, существует возможность подгружать объектные модули (файлы с расширением OBJ) непосредственно к Delphi в процессе сборки приложения. Однако, эта мощная методика имеет ряд ограничений, которые зачастую бывает трудно выдержать.

1.3.2.5 Перевод кода Delphi на C++Builder

Быть может, вы действительно собираетесь ретранслировать все свои программы из Delphi в C++Builder. Или, скорее всего, вам понадобилось наскоро переложить какие-то интересные примеры Delphi на язык C++. В любом случае следует остерегаться подстерегающих вас ловушек и "ложных друзей переводчика". Безусловно, вы преодолеете принципиальные различия синтаксиса объектно-ориентированных языков, а компилятор поможет вам в этом. Опасность скорее таится в ошибочной трактовке простых операторов и понятий, на которые следует обратить внимание.

Оператор членства используется для доступа к любой функции, свойству или переменной, принадлежащих некоторому классу - объявленному на Паскале или на C++. Все объекты Паскаля создаются в куче (heap) и для обращения к перечисленным членам класса используется оператор "точка" (.), например:

Label.Text := 'Hello There;';

Ha C++ дело обстоит несколько сложнее, поскольку объекты могут быть созданы не только в куче, но и на стеке. Для обращения к объекту C++, созданному на стеке, служит оператор прямого членства "точка", например:

TMyCiass myClass;

myClass.DoSomething() ;

Синтаксически приведенная кодовая конструкция сходна с паскалевой. Различие заключается в способе распределения памяти для хранения объекта. Для создания объекта в куче C++ использует оператор new, а для доступа к нему - оператор косвенного членства (->):

TMyCiass* myClass = new TMyCiass;

myClass->DoSomething() ;

delete myClass;

Важно отметить, что если вы можете создавать собственные объекты на стеке или в куче, по своему усмотрению, то объекты VCL (и производные от VCL классов) размещаются только в куче. Поэтому в операциях с объектами VCL всегда используется оператор косвенного членства.

Оператор присваивания в Паскале записывается в виде двоеточия со знаком равенства (: =), а на C++ - это одиночный знак равенства (=). Таким, образом код Delphi:

Label.Top := 20;

должен выглядеть на C++ как:

Label->Top = 20;

Приобретенная в Паскале привычка записи оператора присваивания приводит к раздражающему обилию синтаксических ошибок на C++, впрочем, легко обнаруживаемых компилятором.

Оператор логического равенства в Паскале записывается в виде одиночного знака равенства (=), а на С - это удвоенный знак равенства (==). Таким, образом код Delphi:

if Labell.Text = Label2.Text then ...

должен записываться на C++ как:

if (Labell->Text == Label2->Text) { ... }

Если вы случайно написали одиночный знак равенства в предыдущей инструкции сравнения, то она будет воспринята как операция присваивания - не совсем так, как вы подразумевали. Предупреждение "Possibly incorrect assignment", которое выдаст компилятор, здесь надо трактовать как ошибку. Вообще следует приучить себя доводить программу до полного отсутствия такого рода предупреждений -неизвестно, к каким последствиям они могут привести.

Одиночные и двойные кавычки служат для обозначения текстовых строк. Код Delphi:

Label. Text := 'Иван Иванов' должен выглядеть на C++ как:

Label->Text = "Иван Иванов";

Это различие будет, вероятно, раздражать вас не меньше, чем разница в записи операторов присваивания. Запутывая ситуацию еще более, C++ также использует одиночные кавычки, но совсем для другой цели.

Символьный тип служит для объявления байтовых величин. В Паскале значения символов типа Char заключены в диапазоне от 0 до 255. В C++ символ без знака (unsigned char) эквивалентен описанию Char Паскаля, однако символ со знаком (signed char) имеет другой диапазон значении от -127 до +128. Два варианта присваивания значения некоторому символу на Паскале выглядят как:

с : Char ;

с := #65;

с := Char(0rd('А' ) ) ;

что эквивалентно следующему C++ коду:

char с ;

с = 65;

с = 'А'; // Здесь используются одиночные кавычки.

Заглавные и строчные буквы различаются в C++, поэтому C++Builder требует внимательного обращения с клавишей Shift. Для Паскаля же не имеет значения, верхний или нижний регистр клавиатуры использовался при подготовке текста программы. Если в C++ программе вы используете переменную, объявленную с заглавной буквы, то такая инструкция как:

top = 20;

вызовет ошибку компиляции "Undefined symbol "top"'. Булевы значения "истина" и "ложь" могут записываться на Паскале как true. True, TRUE, TruE и т.д. - как вам больше нравится, хотя по традиции используется нотация True и False (с заглавной буквы). Компилятор C++Builder разрешает использовать типизированные булевы переменные bool, значения которых принято писать строчными буквами.

Ключевое слово Паскаля "with" на C++ не имеет эквивалента, поэтому переводя программу в C++Builder, вам придется добавлять спецификатор класса ко всем свойствам и методам. Таким образом, фрагмент кода на Паскале:

with Label do begin

Top := 20;

Left := 20;

Caption := 'Здравствуй, мир!' ;

end;

на C++ следует переписать в следующем виде:

Label ->Top =20;

Label->Left = 20;

Label->Caption = "Здравствуй, мир!";

Ключевое слово Паскаля "as" на C++ снова не имеет эквивалента, поэтому, переводя программу в C++Builder, следует использовать оператор динамического преобразования типа dynamic_cast. Этот оператор кажется менее удобным, однако его преимущество заключается в том, что проверка допустимости преобразования данного типа не связана с анализом исключений. Таким образом, фрагмент кода на Паскале:

with Sender as TLabel do

Caption := 'Здравствуй, мир1';

на C++ следует переписать в следующем виде:

TLabel* label = dynamic_cast<TLabel*>(Sender);

if (label)

label->Caption = "Здравствуй, мир1";

Паскалевы множества. C++ не поддерживает концепцию типа множества (set), как такового. Вместо множества C++ программисты используют битовые поля, которые не менее эффективны, однако более сложны для понимания и обращения. Поскольку VCL повсеместно использует паскалевы множества, для их интерпретации в C++Builder введен шаблонный класс Set. Множества очищаются посредством метода Clear. Для добавления элементов к множеству используется оператор вставки (<<), а для удаления - оператор экстракции (>>).

<< Предыдущая страница