Для чего нужны классы, если можно все сделать в простой функции? (в C++)

Рейтинг: 2Ответов: 4Опубликовано: 20.02.2015

Изучаю сейчас классы в C++. Для чего они нужны, если можно все сделать в простой функции? Только для того, чтобы все было в объектах?

И еще такой вопрос. Видел, как в классах сразу функции написаны, и видел, как написаны только скелеты функций. Для чего?

Ответы

▲ 12Принят

Этот вопрос, скорее, можно перестроить в более широкий - зачем нужно ООП? Почитайте статью и про ООП вообще. Это действительно довольно большая тема для одного ответа на данном ресурсе. Думаю, поняв концепцию ООП, что такое объект, в чем разница между объектом и классом, Вы придете к выводу, зачем и когда это нужно.

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

Cat cat;
Dog dog;

cat = new Cat(); //создаем кота
dog = new Dog(); //создаем собаку

cat.meow(); //кот мяукает
dog.gav(); //пес лает

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

Обновлено:

Скелеты функций в классе-родителе - это абстракция. Например абстрактный класс Animal, нельзя будет создать объект (т.к. класс абстрактный), ведь не существует объекта просто животного. У него есть абстрактный метод breathing() (дыхание). В дочерних классах (не абстрактных), наличие абстрактного метода breathing() в Animal будет принуждать нас переопределить его. Нам нужно будет переопределить дыхание, например, для рыбы одним способом, для собаки - другим.

В двух словах - абстрактный класс - класс, от которого нельзя создать экземпляр. Служит для хранения общей логики. Абстрактный метод (скелет) - требует от программиста переопределения в дочерних классах. Логика у каждого может быть своя, а наличие обязательно.

▲ 4

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

▲ 3

Разделение скелета и функций нужно вот для чего:

Допустим, программа состоит из нескольких файлов (a.cpp, b.cpp, c.cpp), которые пользуются классом из модуля x.cpp. После компиляции все четыре файла должны стать одним исполняемым файлом. Но чтобы из файлов a.cpp, b.cpp, c.cpp обращаться к классу, описанному в x.cpp, им нужно знать, как этот класс "выглядит". Если просто во всех модулях подключить x.cpp через #include "x.cpp", то во всех файлах продублируется не только описание класса, но и все его функции, ну и компилятор, скорее всего, откажется компилировать. Чтобы подобного дублирования не было, нужно каркас класса (без функций) вынести в файл x.hpp, и в файлах a.cpp, b.cpp, c.cpp и x.cpp подключать именно его через #include "x.hpp", тогда никакого дублирования кода не будет и все нормально скомпилируется.

В простых случаях, когда класс используется только в том файле, в котором описан, все его функции можно прописывать прямо в его теле.

▲ 2

Алан Кей, вспоминая о том, как он придумал объектно-ориентированное программирование, рассказывал, что на его образ мыслей одновременно повлияли как его биологическое образование, так и математическое.

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

Математическая же часть его образования помогла ему понять, что в программировании всё точно так же, как и в алгебре. Операции, ассоциированные с разными классами объектов, имеют между собой очень много общего. И, соответственно, было бы неплохо иметь возможность определять общую часть этих операций сразу для множества различных классов, а какие-то специфические нюансы уже уточнять в каждом классе отдельно.

Вот если посмотреть на программирование через призму такого восприятия, то вроде бы становится очевидно, зачем нужны классы. Единственный вопрос, который остаётся, - это вопрос о том, почему в С++ объекты взаимодействуют не через сообщения (как в SmallTalk'е), а напрямую. Это, очевидно, было сделано для скорости.