Простое введение в C++. Часть 1. Классы

В этой статье мы рассмотрим простое и понятное введение в С++. Хотя C++ кажется сложным, но это происходит потому, что при его описании используют много туманных абстракций и лишних терминов.

Мы же рассмотрим C++ без всякой философии, с точки зрения программиста-практика.

1. Сравнение С и С++

Начнем с хорошей новости. Язык C++ — это клон языка C, в который были добавлены средства работы с классами. Поэтому, если вы знаете язык C, то вы уже на 90% знаете C++.
Первоначально C++ так и назывался «Си с классами», но потом решили дать более «си-шное» название, то есть добавили единичку к C. Поэтому нам нужно разобраться только с программированием в классах. Что мы сейчас и сделаем

2. Создание нового проекта

Запустите CodeBlocks, создайте новый проект и выберите шаблон «Console application».

Нажмите «Перейти».

Выберите C++ и нажмите Next.

Укажите папку и имя файла и нажмите Next.

Нажмите Finish. Вы получили минимальную программу на C++.

Нажмите F9 для компиляции и запуска программы.

Все работает.

3. Пример на С

Так как C++ — это клон C, то мы можем писать код, как обычно мы это делаем в языке C. Сделаем это, чтобы потом сравнить отличия. Напишем следующую программу:

В этой программе все просто. Есть две переменных x и y, и есть функция Sum, которая складывает два числа. Обозначение «cout <<» можно рассматривать как вариант функции printf.

Скопируйте этот текст и убедитесь, что все работает.

4. Главный секрет C++

А теперь мы напишем ту же самую программу, но уже с классами. И для этого нам нужно знать главный секрет C++.

Главный секрет C++
Класс — это объединение кода и данных.

Как видите, секрет достаточно прост. Запишем нашу программу но уже с помощью класса:

Итак, что мы сделали?

Мы создали класс Summa с помощью ключевого слова class. Но класс — это просто шаблон. Для использования класса нужно получить экземпляр класса. Это мы сделали в строке «Summa s;». После того, как эта строка выполнится, мы получим экземпляр класса, к которому же можно обращаться. При этом переменные класса называются свойства, а функции класса называются методы.

Обратите внимание, что функция Sum не требует указания параметров, потому она берет эти параметры из свойств класса.

Обращение к свойствам и методам производится с помощью точки. Например, «s.x» — означает, что мы обращаемся к свойству экземпляра s класса Summa.

Ключевое слово public означает, что свойства и методы класса доступны вне класса.

5. Наследование классов

И теперь познакомимся с ключевым понятием программирования в классах — наследованием.

Опять же сравним с чистым Си.

Допустим, что нам нужно не только суммировать числа, но и удвоить результат. В языке Си один вариантов это сделать — использовать вложенную функцию:

В этом примере функция Sum2 использует вызов функции Sum. Важный момент здесь в том, что те параметры, которые были переданы на вход функции Sum2 просто передаются на вход функции Sum. Такая сквозная передача параметров — это обычная практика C.

Но мы видели, что в классе мы параметры не использовали. Как же их передать? Для этого в C++ используется наследование.

В этом примере в строке «class Summa2 : public Summa» мы указываем, что класс Summa2 наследуется от класса Summa. Это позволяет обратиться к свойствам и методам наследуемого класса.

Там где в С используются вложенные функции, там в C++ используются вложенные классы.

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

И несколько слов надо сказать про рекламную чепуху вокруг C++. Обычно в книжках про C++ пишут о том, что программирование в классах позволяет не больше и не меньше как моделировать весь мир. Это весьма странное заявление. Любая программа — это код и данные. Их можно написать отдельно, можно объединить в общую структуру, но от этого принципиально ничего не меняется. Любая программа на С может быть переписана в классах, а любая программа в классах может быть переписана на С.

То есть C++ не дает программисту какого-то ключевого преимущества, именно поэтому язык C++, который позиционировался как замена C, так и не смог его заменить. Для интереса можно посмотреть TIOBE-рейтинг этих языков в сентябре 2018.

Простое введение в C++. Часть 2. Конструкторы и деструкторы

Комментарии 21

  • Уважаемый Константин!
    Вы написали: «Класс – это объединение кода и данных».
    А В ваших «классах» нет данных, там лишь публичные переменные, которые лишают Ваш код одной из главных фишек ООП — объект = чёрный ящик, нельзя ковыряться во внутренностях объекта.
    https://jug.ru/2016/09/bugayenko-west/

    • >А В ваших “классах” нет данных
      Переменные — это тоже данные. Добавьте массив — суть примера не изменится.
      >там лишь публичные переменные
      Добавьте приватную переменнную — суть примера не изменится.
      >из главных фишек ООП объект = чёрный ящик, нельзя ковыряться во внутренностях объекта.
      Это не фишка ООП, а обычная практика языка Си (да и других языков). Если программист — это автор объекта, то он может «ковыряться во внутренностях» сколько угодно. Если программист не автор объекта, а объект скрыт в модуле, то доступа к нему нет.

      • Уважаемый Константин!
        Если Вы считаете, что «автор объекта, то он может “ковыряться во внутренностях” , то Вы лишили себя инкапсуляции. А лишили Вы себя, как и многие другие, потому что уже научились хорошо программировать процедурно. Без инкапсуляции в ООП вы как рычаг без точки опоры. https://inexsu.wordpress.com/2018/07/28/%D0%BE%D0%BE%D0%BF-%D1%80%D0%B0%D0%B7%D1%80%D1%83%D1%88%D0%B8%D1%82%D1%8C-%D1%81%D0%BE%D0%B1%D0%BE%D1%80-%D0%BF%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B8%D1%82%D1%8C-%D0%B1%D0%B0%D0%B7%D0%B0%D1%80/

        • До капсуляции дело еще не дошло. Это просто описание, что такое класс.

        • И насчет «ковыряния во внутренностях». Инкапсуляция (encapsulation) — технология объединения собственно данных и методов их обработки (в одном компоненте). Это и показано в приводимом коде, где в классе размещены и данные (переменные x и y) и метод их обработки (функция Sum()). А что касается недоступности внутренностей объекта, так это называется сокрытием (hiding). Причём в программировании это означает скрытие внутренней реализации компонента от других компонентов, а не от программиста. Например, доступ к скрытой переменной может предоставляться не напрямую, а с помощью методов для чтения (геттер) и изменения (сеттер) её значения. По аналогии ООП с окружающими нас объектами: внутренности бытовой техники доступны тем, кто их создаёт, а потом их одевают в кожухи, защищающие их от непосредственного контакта с другими приборами, сетью, а также ограничивая доступ простых пользователей, и предоставляя для этого специальные интерфейсы, пульты управления… Если надо для ремота, то ремонтёр может снять и кожух, и даже разобрать на детали…
          Так что, если в сообществе C++, как и Java, и принято рассматривать инкапсуляцию без сокрытия как неполноценную, но считать это одним и тем же или подменять одно другим — заблуждение. Тем более есть языки, например, Smalltalk, Python, где реализуют инкапсуляцию в полной мере, не предусматривая возможности скрытия в принципе, и есть языки, такие как Standard ML, OCaml, где жёстко разделяют эти понятия и предоставляют их в семантически различном виде.

    • Странно, что Михаил критикует данную статью Константина на несоответствие кода объектно-ориентированному программированию. Ведь статья посвящена классам в языке С++, а не ООП в языке С++, тогда как язык С++ мультипарадигмальный и допускает кроме объектно-ориентированного программирования обобщённое, процедурное и метапрограммирование. Причём приводит ссылку на статью «Классы — это не объектно»: интервью Егора Бугаенко с Дэвидом Уэстом (https://jug.ru/2016/09/bugayenko-west/), где, согласно этой статье, C++ не задумывался как объектно-ориентированный, классы — это не объектно-ориентированно и не имеют отношения к объектам, а самый объектно-ориентированный язык — Self. Вот цитаты из этой статьи:
      «Но вообще-то C++ не объектно-ориентированный, он никогда и не задумывался таким. Если почитать, что Страструп писал во время создания C++ … Но он ни разу не называет его объектно-ориентированным языком. Другие люди сказали: «Ну, у вас в C++ классы, значит, вы объектно-ориентированные, как Smalltalk». Но ООП не было задумкой.»
      «Так что, например, всё понятие класса — это не объектно-ориентированно. Классы не имеют никакого отношения к объектам. Но они были способом эффективно хранить код, позволяя вносить изменения в одном месте вместо многих сразу.
      Ближайшее, что когда-либо было к настоящему ОО-языку — Self. Там нет ничего, кроме объектов, там только один класс, или один тип сущностей, и эта сущность — объекты. Там можно использовать методы и переменные, можно клонировать, но нет такого явления, как класс.»

    • А статья интересная! Ещё одна цитата:
      Дэвид: Ну, как я попытался сказать в книге, класс ничего не должен делать. В Smalltalk есть методы классов, но не надо их использовать. Их использование — возвращение к командному способу мышления. Вы берёте то, что должно быть ответственностью объектов, и по каким-то причинам пытаетесь запихнуть это всё в класс. И в итоге класс делает многое за объекты.

  • Все сиплюcплюcшники рекомендуют переменные делать недоступными, и по умолчанию так и есть, по умолчанию доступны методы, а вот в си уже изначально присутствует структура данных struct, не помню, может ли входить метод в структуру языка си, но в структуре си++ как раз наоборот, данные доступны по умолчанию и требуют объявления public а вот методы-функции не доступны по умолчанию, но у класса присутствует конструктор и деструктор, вот что важно, это метод, который есть и по умолчанию и он создаёт объект и может быть определён программистом, а вот у структур такого нету… Казалось бы структура и класс почти одно и тоже, но не совсем. Я бы вот хотел дополнить, что класс это всё таки не шаблон, строго говоря, а новый тип данных, или тип объекта, в котором присутствует «жизнь» не только как набор переменных и констант этаких «существительных», но и «глаголов» , то есть действий с данными. Деструктор тоже можно определить по-своему. А шаблонами в языках программирования называют записи для компиляторов с использованием инструкций для компилятора (макрокоманды), на стадии получения исполняемого или объектного кода, и ещё шаблоном можно бы назвать определение виртуальных функций…. Вообще-то есть у Си++ библиотека шаблонов, шаблонное программирование, там много новеньких понятий для программиста на фортране-79. В общем программирование с классами, это объектно-ориентированное программирование, в котором можно определить свои куски кодов, которые создаются и уничтожаются в программе по мере использования и даже если программист не знает текста а знает что делает объект некоего класса, на основе одного класса он может определить объект своего класса с помощью наследования и работать с ним, они наслаиваются и наслаиваются эти классы.

    • >класс это всё таки не шаблон
      В данной статье слово «шаблон» используется в общепринятом смысле, а не в смысле языка C++.
      >программирование с классами, это объектно-ориентированное программирование
      Нет. Объектно-ориентированное программирование — это стиль программирования, который можно использовать, а можно и не использовать при программировании с классами.

  • Автор застрял в светлом прошлом и явно не хочет смотреть в будущее,а примеры с наследованием особенно неудачные. Аналогия с генетикой и живыми объектами природы,когда каждый из них получал новые свойства и меры,которыми эти объекты используют,чтобы воплощать свои способности.
    И ещё,эти два языка нельзя рассматривать по отдельности( C и C++) -они применяются вместе в одном проекте по мере необходимости.Так как по традиции все операционные системы написаны на чистом Си,то конечно он будет лидировать.
    Но почему то до по явления C# в прикладом программировании был популярен Pascal Delphi.

    • >примеры с наследованием особенно неудачные.
      Суть примеров — показать, как устроен язык C++.
      Если не нравится, то приведите удачный пример наследования, только не абстрактные рассуждения, а конкретный код. Аналогии — это хорошо, но программисту платят не за аналогии, а за написание программ.
      >они применяются вместе в одном проекте по мере необходимости.
      При программировании в стиле ООП их совмещать нельзя. А так, конечно, при желании можно написать программу, хоть на десяти языках сразу.

    • «Аналогия с генетикой и живыми объектами природы,когда каждый из них получал новые свойства и меры,которыми эти объекты используют,чтобы воплощать свои способности.» — тут соглашусь. Пример приведенный автором напомнил мне школьный курс, начала 90-х. Хорошим примером использования ООП является примерны реального мира.
      Но далее у меня уже серьезные разногласия возникают:
      1) «И ещё,эти два языка нельзя рассматривать по отдельности( C и C++) -они применяются вместе в одном проекте по мере необходимости.» — это где вы такое видели? Ну точнее кончено могут быть программы написанные отдельно на C и отдельно на C++, в рамках одного проекта, но вместе код не может быть использован. Не встречал подобных IDE и компиляторов. Может быть конечно Eclipse или NetBean, последних версий, умеют осуществлять такую сборку…
      2) «Так как по традиции все операционные системы написаны на чистом Си» — давайте будем честны, далеко не все. Раньше все ОС писали на ассемблере.

  • Спасибо большое. Очень методично.

  • Изучаю С++ на английском, на этом простом примере всё стало ясно, в примерах данных в колледже очень все сложно и я потеряла суть простой схемы. Спасибо, Константин, за работу, продолжаю читать Ваши материалы.

  • изучаю Си и ++ что все понятно спасибо Константин
    мне подробно скажите про библиотека

  • Прекрасное введение в С++ на уровне аналогий.
    А комментарии «знатоков» явно не по делу. Особенно меня умилил комментарий о С# и Дельфи. Автор путает грешное с праведным. Речь идет о программировании под windows. Мелкософт для этого изобрел win API с графической системой gdi, между нами говоря, очень неудобной. Объектно ориентированное программирование ее не спасло. Одновременно Borland разработала графическую систему bgi. Она-то и реализована в Дельфях.
    Когда Borland преставилась одного из разработчиков bgi перекупила мелкософт. Он написал windows forms, ясное дело под влиянием bgi. А для ее реализации сварганили С#. Так что С# в какой-то мере потомок Дельфи.

  • Да, как-то набросились некоторые «знатоки» с критикой «не в строчку». А может вы, Константин, нарушили «Правило чистой энергии» в своей критике языка C++, когда сравнивали его с чистым C?
    В принципе, сайт для начинающих программировать. А начинающим ошибаться простительно. Как писал Страуструп: «слишком многие ошибочно полагают, что их первый язык программирования — самый лучший. Язык С++ во многих отношениях прекрасный язык, но он не идеален; впрочем, то же самое можно сказать о любом языке программирования.».

    • Если посмотреть на статистику, то C++ так и не смог приблизиться к популярности к C. Я объясняю, почему так произошло.

  • Как я прочитал на Хабрахабре: Объектно-ориентированное программирование это стиль программирования, а классы — это синтаксический сахар, предоставляемый языком программирования, таким как C++. То есть программировать с использованием классов ещё не означает ООП, а в стиле ООП можно программировать и без использования классов.
    Объектно-ориентированное программирование это целая парадигма, в которой даже несколько подходов и соответсвующих стилей (в зависимости от предоставляемых языком средств синтаксиса):
    — класс-ориентированный подход (Simula, Smalltalk, PHP, C++, Java, C#, Objective-C, Perl, Ruby, Eiffel)
    — агентно-ориентированный подход (распределённые объектные архитектуры (CORBA, DCOM, Java RMI, WEB-services), распределённая объектная среда JADE)
    — компонентно-ориентированный подход (Oberon, Component Pascal, Java, платформа .NET, Rails Cells)
    — прототипно-ориентированный подход (языки Self, JavaScript, Lua, Io, REBOL и др.)
    Парадигма программирования не определяется однозначно языком программирования (практически все современные языки в той или иной мере допускают использование различных парадигм). Так, на языке Си, который не является объектно-ориентированным, можно работать в соответствии с принципами объектно-ориентированного программирования (хотя это и сопряжено с определёнными сложностями). Кому интересно:
    Ben Klemens. 21st Century C (2nd Edition; см. глава 11. Object-Oriented Programming in C)
    и даже
    Axel-Tobias Schreiner. Object-Oriented Programming With ANSI-C

    • К сожалению, понятие классов и объектов меняется от языка к языку. На данный момент классическое ООП реализовано только в C++. Другие языки реализовали свою версию.

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.