Миграция с Delphi на Visual C++

Введение

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

Delphi зарекомендовала себя как удобная среда для быстрого создания Windows-приложений с оконным интерфейсом. Из этой статьи вы узнаете, как делать то же самое на языке C++ в среде MS Visual Studio 2008. По счастью, принципы конструирования пользовательского интерфейса в последних версиях этой среды практически совпадают с теми, что присутствуют в Delphi.

Предполагается, что читатель хотя бы минимально знаком с синтаксисом языка C (без плюсов). В статье дается краткое описание работы с классами и объектами и ряда свойственных языку Visual C++ нововведений (пространства имен, управляемые указатели и пр.) Затем, рассказывается о создании пользовательского интерфейса и обработчиков событий. Также рассказано о том, как организовать ввод и вывод числовых параметров и, соответственно, о переводах строк в числа и наоборот.

Содержание

1. Установка среды

Если среда еще не установлена, скачиваем с Микрософтовского сайта бесплатную редакцию MS Visual Studio C++ 2008 Express.

[Скачать]

Недавно вышла Visual Studio 2010, но ее скачивать не советую — там IntelliSence (подсказки названий методов и типов параметров) для языка C++ не работает.

Студию надо зарегистрировать (меню Help/Register product), иначе через месяц перестанет работать. Регистрация бесплатна.

Отличие от полной версии:
1) Среда содержит только один язык программирования.
2) Нет компилятора в 64 битный код.
3) Нет плагинов, дизайнера классов и некоторых других инструментов.

Полный список отличий смотрите здесь: Выпуски Visual C++

2. Некоторые предварительные сведения о языке C++

Чтобы понять, как создаются простейшие оконные приложения, мне пришлось разобраться с нижеперечисленными особенностями языка C++.

2.1. Пространства имен

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

namespace SampleName {
  //Опишем для примера переменную
  int x;
}

Данный блок определяет пространство имен SampleName. Если мы захотим использовать любой идентификатор, описанный в этом блоке (например, переменную x), где-то за пределами блока, нам придется обращаться к нему как SampleName::x

Оператор :: носит название оператора глобального разрешения имен.

Если разместить в программе строку:

using namespace SampleName;

то в последующем тексте название этого пространства имен можно не писать, оно добавится автоматически.

Пространства имен иерархичны. То есть, если например, написано

namespace SampleName1 {

  namespace SampleName2 {
    int x;
  }

}

то к переменной x придется обращаться SampleName1::SampleName2::x.

2.2. Классы и объекты

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

/******************************
** Описание простого класса
*******************************/
class SampleClass
{
  public:
    //Пример элемента данных (информационного поля)
    int x;

    //Конструктор
    //1. Имя конструктора совпадает с именем класса
    //2. Конструктор не должен возвращать никакого значения,
    //   слово void перед ним не ставится
    SampleClass();

    //Деструктор
    //1. Имя деструктора состоит из символа «~» и имени класса
    //2. Деструктор не должен возвращать никакого значения,
    //   слово void не ставится.
    ~SampleCalass();
  private:
    //Обычный метод
    void DoSomething(int a);
};
//Реализация метода.
//Перед именем метода ставится имя класса и оператор глобального
//разрешения имен. По сути, имя класса играет роль пространства имен
void SampleClass::DoSomething(int a)
{
  //Something
}
//Тело конструктора
SampleClass::SampleClass(){
  x = 0;
}

Чтобы создать класс наследник пишем имя предка через двоеточие после имени класса:

class Sample2 : public SampleClass
{
  …
}

Создать объект мы можем двумя способами:

SampleClass S1, S2;
SampleClass *PS = new SampleClass();

В Delphi объекты (экземпляры класса) представляли собой указатели. Этому случаю соответствует второй вариант (PS). Объекты же S1 и S2 представляют собой обычные переменные, и при присваивании будет происходить копирование значений полей.

Указатель на объект можно описать, не создавая самого объекта:

SampleClass *PS2;

В этом случае ему можно присвоить адрес другого объекта, например:

PS2 = PS;

или

PS2 = &S1; //& - операция взятия адреса.

Обращения к полям и методам объекта – обычной переменной происходит, как в Delphi, через точку:

S1.x = 42;
S1.DoSomething(42);

К элементам объекта-указателя можно обратиться предварительно разименовав его:

(*PS).x = 42;

или сразу, используя оператор «->» (стрелка).

PS->x = 42;

2.3. Управляемые указатели

Управляемые указатели появились, начиная с версии Visual C++ 2002. Основные отличия от обычных:
1) При описании такого указателя вместо знака * используется ^.
2) Выделенную по них память не надо освобождать – об этом позаботится автоматический сборщик мусора.
3) Для выделения памяти вместо new аналогично используется gcnew.

2.4. Статические поля и методы

Объявляя поле или метод в классе можно поставить перед ним слово static:

class Sample
{
public:
  static int x;
  static void DoSomething();
}

Статическое поле будет общим для всех объектов класса Sample. Изменив его у одного объекта, мы автоматически изменим его во всех остальных объектах. Задать его значение можно, даже когда ни одного объекта данного класса не создано. Для этого приставляем к его имени имя класса:

Sample::x = 42;

К статическому методу также можно обратиться, даже если объектов еще нет. Например, существует полезный класс Convert, содержащий статические методы для преобразования данных одного типа в другой. Например:

String ^Str = "42"; //Управляемый указатель, кстати
//Преобразуем эту строку в соответствующее целое число
int x = Convert::ToInt32(Str);

2.5. Сворачиваемая область #pragma region

Как всякая современная среда разработки Visual Studio дает возможность сворачивать и разворачивать отдельные блоки программы. Скажем, по умолчанию есть возможность свернуть описание класса или функции. Директива #pragma region позволяет явным образом ограничить кусок кода, который можно будет сворачивать и разворачивать:

#pragma region RegionName
  //Сворачиваемая область
#pragma endregion Comment

Вместо RegionName следует поставить любой текст. Он будет отображаться, когда область свернута. Comment также замените на произвольный комментарий.

3. Создание оконного приложения

3.1. Создание приложения

Чтобы создать приложение с оконным интерфейсом, выберите пункт меню File \ New \ Project…. В появившемся диалоговом окне выполните действия, перечисленные на рисунке ниже:

Создание оконного приложения в Visual C++ 2010 Express

После этого в центре экрана вы увидите закладку Form1.h [Design] с визуальным конструктором формы.

Нажав F5 можно скомпилировать и запустить проект. В результате вы увидите пустое окно вашей программы.

3.2. Конструирование интерфейса

Расположение панели элементов в MS Visual C++ 2010 Express

Перейдите на закладку Form1.h [Design]. Вы увидите изображение пустой формы. Аналог палитры компонентов называется Toolbox (в русской версии «Панель элементов»). Попасть туда можно, нажав Ctrl – Alt – X или нажав на одноименную закладку, которая обычно располагается справа (см. рисунок).

Здесь вы увидите знакомые элементы вроде Button, Label, Checkbox и т.д. Хватайте их и тащите на изображение формы. Для примера давайте разместим на форме кнопку (Button), текстовое поле (TextBox) и надпись (Label).

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

Окно свойств объекта

Перейдите к списку событий для кнопки и двойным щелчком мыши напротив события Click создайте соответствующий обработчик. Для примера давайте по нажатию кнопки выводить в Label слова ”Hello, World!”. Для этого в обработчик события поместим инструкцию:

label1->Text = "Hello, World!";

Обратите внимание, что все компоненты (в частности label1) являются управляемыми указателями. Соответственно, к их свойствам следует обращаться не через точку, а через стрелку «->».

Рассмотрите получившийся файл Form1.h. Приведенной в разделе 1 информации должно быть достаточно, чтобы понять смысл всего, что там теперь написано.

3.3. Преобразование числа в строку и обратно

Свойство Text имеет тип String^, то есть это управляемый указатель на объект типа String. Соответственно, чтобы организовать ввод/вывод числовых данных необходимо уметь преобразовывать строки в числа и наоборот. Для этого имеется полезный класс Convert, содержащий статические методы для преобразования значений одного типа в другой. Для нашей задачи полезными будут следующие методы:

ToString() – преобразует значения любого числового типа в значение типа String.

ToDouble() – преобразует строку в вещественное значение двойной точности (double).

ToSingle() – преобразует строку в вещественное значение одинарной точности (float).

ToInt32() – преобразует строку в значение типа int.

Для примера считаем числовое значение из компонента textBox, умножим его на 2, а результат поместим в label. Соответствующий обработчик событий будет выглядеть следующим образом:

	private: 
	  System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
				
				float i = Convert::ToSingle(edit1->Text);
				i = i * 2;
				label1->Text = Convert::ToString(i);

	  }

14 комментариев

  1. Антон

    Благодарю:) отличная статья, коротко и ясно!

  2. Кирилл

    Спасибо большое отличная статья очень долго искал преобразование строки в число и обратно. а тут так просто написано!!!

  3. C++ Developer

    Эта статья просто супер! Мне она очень понравилось. :)

  4. C++ Developer

    (понравилась) ;)

  5. Максим

    Спасибо, как раз то что искал

  6. Игорь

    Благодарен за статью!

  7. Сергей

    Порекумендуйте книгу где было точно также все разжовано и описано плиз Prostyakov1985@yandex.ru

  8. Taras

    Разжеванные особенности C++ мне нравятся в изложении Липмана и Лажойе:

        Липман, Лажойе.Язык программирования C++. Вводный курс.

    Скачать можно также здесь: http://www.twirpx.com/file/8260/

    За быстрой справкой по каким-нибудь функциям или классам STL я хожу на http://www.cplusplus.com/reference/

    Ну, а особенности конкретно Visual C++ (как там создавать оконные приложения и т.п.) ищу, так сказать, в первоисточнике, на http://msdn.microsoft.com/. По-началу, найти там что-то было трудно, но потом я привык, понял куда ходить, куда не ходить. Вобщем, если тебя не пугает английский язык, то как справочник вполне можно использовать.

  9. Жика

    Отличная статья!!! Коротко и ясно!!!

  10. Юрий

    про конвертацию строк отлично

  11. Евгений

    Статья ни о чем. И уж тем более не про миграцию, под которой, я понимаю перенос приложения.

  12. Виталий

    Для не программировавшего ранее в VS очень даже полезная статья — позволяет через несколько минут изучения приступить непосредственно к программированию GUIни на V С++, если конечно опыт программирования в С++ есть.

  13. Александр

    Отличная и полезная статья начинающим!

Добавить комментарий