Классы представляют собой расширенную концепцию структур данных : как и структуры данных, они могут содержать поля, но они также могут содержать функции в качестве членов.
Объект — это экземпляр класса. С точки зрения переменных класс будет типом, а объект будет переменной.
Классы определяются как с использованием либо ключевого слова class, так и с помощью ключевого слова struct, со следующим синтаксисом:
class class_name < access_specifier_1: member1; access_specifier_2: member2; . >object_names;
Где class_name — это допустимый идентификатор для класса, object_names — это необязательный список имен объектов этого класса. Тело объявления может содержать члены, которые могут быть объявлениями как полей, так и методов, и, возможно, спецификаторы доступа.
Классы имеют тот же формат, что и простые структуры данных, за исключением того, что они могут также включать методы и иметь спецификаторы доступа. Спецификатор доступа — одно из следующих трех ключевых слов: private, public или protected. Эти спецификаторы изменяют права доступа для членов, которые следуют за ними.
Что такое класс | ООП C# | Что такое объект класса | Экземпляр класса | C# Уроки | # 55
- закрытые (private) члены класса доступны только из других членов этого же класса (или из его «друзей»);
- защищенные (protected) члены доступны из других членов этого же класса (или из его «друзей»), а также из членов производных классов;
- открытые (public) члены доступны везде, где доступен объект.
По умолчанию все члены класса, объявленного с помощью ключевого слова class, имеют закрытый (private) доступ. Следовательно, любой член, который объявлен перед любым другим спецификатором доступа, автоматически получает закрытый доступ. Например:
class Rectangle < int width, height; public: void set_values (int,int); int area (void); >rect;
Этот код объявляет класс (т.е. тип), называемый Rectangle, и объект (т.е. переменную) этого класса, называемую rect. Этот класс содержит четыре члена: два поля типа int (width и height) с закрытым доступом (поскольку private — это уровень доступа по умолчанию) и два метода с открытым доступом: методы set_values и area, для которых сейчас имееотся только объявление, но не определение.
Обратите внимание на разницу между именем класса и именем объекта. В приведенном примере Rectangle является именем класса (т.е. типом), тогда как rect является объектом типа Rectangle. В таком же отношении находятся int и a в следующем объявлении:
int a;
Где int — это имя типа (класс), а a — имя переменной (объект). После объявления Rectangle и rect, любой из открытых членов объекта rect может быть доступен, как если бы они были обычными функциями или обычными переменными, вставкой точки (.) между именем объекта и именем члена. Это повторяет синтаксис доступа к членам простых структур данных. Например:
rect.set_values (3,4); myarea = rect.area();
Единственными членами rect, к которым нельзя получить доступ из-за пределов класса, являются ширина и высота, поскольку они имеют закрытый доступ, и на них можно ссылаться только из других членов этого же класса.
C# — Класс и объект. Уроки для маленьких и тупых #8.
Ниже приведен законченый пример класса Rectangle:
// пример класса #include using namespace std; class Rectangle < int width, height; public: void set_values (int,int); int area() >; void Rectangle::set_values (int x, int y) < width = x; height = y; >int main ()
area: 12
В этом примере содержится оператор разрешения области видимости (::, два двоеточия), который встречался в предыдущих главах в отношении пространств имен (namespaces). Здесь он используется в определении функции set_values , чтобы определить член класса вне самого класса.
Обратите внимание, что определение метода area было включено непосредственно в определение класса Rectangle с целью упрощения. И наоборот, прототип set_values просто объявляется в классе, но реализация метода находится за пределами класса. В этом внешнем определении оператор разрешения области видимости (::) используется для указания, что определяемая функция является членом класса Rectangle, а не обычной функцией.
Оператор разрешения области видимости (::) указывает класс, к которому принадлежит определяемый член, и предоставляет точно такую же область видимости, как если бы это определение функции было непосредственно включено в определение класса. Например, функция set_values в предыдущем примере имеет доступ к переменным width и height, являющимся закрытыми членами класса Rectangle, и таким образом доступным только из других членов класса, таким как этот.
Единственным различием между определением метода полностью внутри определения класса и включением одного только объявления метода и определением его после вне класса является то, что в первом случае метод автоматически считается компилятором подставляемым (inline), в то время как во втором случае он считается обычным методом. Это не вызывает различий в поведении, но может влиять на оптимизацию.
Поля width и height имеют закрытый доступ (если не указаны иные спецификаторы доступа, все члены класса, определенного ключевым словом class, имеют закрытый доступ). Объявление их закрытыми делает невозможным доступ к ним извне класса. Это имеет смысл, так как мы уже определили метод для задания значений этим полям внутри объекта: метод set_values. Таким образом, остальная часть программы не должна иметь прямого доступа к ним. Возможно, в таком простом примере, как этот, сложно увидеть, как ограничение доступа к этим полям может быть полезно, но в больших проектах может быть очень важно, чтобы эти значения не могли быть изменены неожиданным образом (неожиданным с точки зрения объекта).
Наиболее важным свойством класса является то, что он является типом, и мы можем объявить множество объектов этого типа. Например, как и в предыдущем примере класса Rectangle, мы можем объявить объект rectb в дополнение к объекту rect:
// пример: один класс, два объекта #include using namespace std; class Rectangle < int width, height; public: void set_values (int,int); int area () >; void Rectangle::set_values (int x, int y) < width = x; height = y; >int main ()
rect area: 12 rectb area: 30
В данном конкретном случае, класс (тип объектов) это Rectangle, два экземпляра (т.е. объекта) которого создаются: rect и rectb. Каждый из них имеет свои собственные поля и методы.
Обратите внимание, что вызов rect.area() не дает того же результата, что вызов rectb.area(). Это потому что каждый объект класса Rectangle имеет свои собственные переменные width и height, а также в некотором роде свои собственные методы set_value и area, которые оперируют с собственными полями объекта.
Классы позволяют программировать с использованием объектно-ориентированной парадигмы: Данные и функции являются членами объекта, уменьшая необходимость передачи и обработки других переменных в качестве аргументов функции, потому что являются частью объекта, член которого вызывается. Обратите внимание, что методам rect.area и rectb.area не передаются аргументы. Эти методы используют непосредственно поля соответствующих объектов rect и rectb.
Конструкторы
Что произойдет в предыдущем примере, если мы вызовем метод area до вызова set_values? Результат не определен, так как полям width и height никогда не присваивается значение.
Чтобы избежать этого, класс может включать специальный метод, называемый конструктором, который автоматически вызывается каждый раз, когда создается новый объект этого класса, позволяя классу инициализировать поля или выделить память.
Конструктор объявляется как обычный метод, но с именем, которое совпадает с именем класса, и не имеет возвращаемого значения, даже void.
Класс Rectangle можно легко улучшить путем реализации конструктора:
// пример: конструктор класса #include using namespace std; class Rectangle < int width, height; public: Rectangle (int,int); int area () >; Rectangle::Rectangle (int a, int b) < width = a; height = b; >int main ()
rect area: 12 rectb area: 30
Результат этого примера будет идентичен результату из предыдущего примера. Но сейчас класс Rectangle не имеет метода set_values, а вместо этого имеет конструктор, который выполняет аналогичные действия: он инициализирует значения width и height значениями аргументов, переданных в него.
Обратите внимание, каким образом эти аргументы передаются в конструктор в момент, когда объект этого класса создается:
Rectangle rect (3,4); Rectangle rectb (5,6);
Конструкторы не могут вызываться явно, как если бы они были обычными методами. Они выполняются только один раз, когда создается новый объект этого класса.
Обратите внимание, что ни в объявлении прототипа конструктора (внутри класса), ни в его реализации, не должно быть возвращаемого значения, даже void: конструкторы никогда не возвращают значения, они просто инициализируют объект.
Перегрузка конструкторов
Как любая другая функция, конструктор может иметь перегрузки, принимающие различные параметры: различное число параметров и/или параметры различных типов. Компилятор автоматически вызовет тот, параметры которого совпадут с аргументами:
// перегрузка конструкторов класса #include >iostream> using namespace std; class Rectangle < int width, height; public: Rectangle (); Rectangle (int,int); int area (void) >; Rectangle::Rectangle () < width = 5; height = 5; >Rectangle::Rectangle (int a, int b) < width = a; height = b; >int main () < Rectangle rect (3,4); Rectangle rectb; cout >> «rect area: » >> rect.area() >> endl; cout >> «rectb area: » >> rectb.area() >> endl; return 0; >
rect area: 12 rectb area: 25
В этом примере создаются два объекта класса Rectangle: rect и rectb. rect инициализируется конструктором с двумя аргументами, как в примере выше.
Но в этом примере также представлен специальный вид конструктора: конструктор по умолчанию. Конструктор по умолчанию — это конструктор, не принимающий аргументов, и он является специальным конструктором, потому что вызывается, когда объект объявляется, но не инициализируется какими-либо аргументами. В приведенном выше примере, конструктор по умолчанию вызывается для rectb. Обратите внимание, что rectb создается без пары круглых скобок — фактически, пустые круглые скобки не могут быть использованы для вызова конструктора по умолчанию:
Rectangle rectb; // вызывается конструктор по умолчанию Rectangle rectc(); // конструктор по умолчанию НЕ вызывается
Это происходит потому, что пустые круглые скобки делают rectc объявлением функции, ане объявлением объекта: это будет функция, не принимающая аргументов и возвращающая значение типа Rectangle.
Унифицированная инициализация
Способ вызова конструктора путем заключения агрументов в круглые скобки, как показано выше, известен как функциональная форма. Однако, конструкторы также могут быть вызваны другими способами:
Во-первых, конструкторы с одним параметром могут быть вызваны с использованием синтаксиса инициализации переменной (использование знака равенства):
class_name object_name = initialization_value;
Совсем недавно в C++ появилась возможность вызова конструкторов с использованием унифицированной инициализации, которая по сути является такой же, как функциональная форма, но использует фигурные скобки (<>) вместо круглых (()):
При необходимости этот последний синтаксис может включать знак равенства перед фигурными скобками.
Вот пример с четырьмя способами создать объект класса, конструктор которого принимает один параметр:
// классы и унифицированная инициализация #include using namespace std; class Circle < double radius; public: Circle(double r) < radius = r; >double circum() >; int main () < Circle foo (10.0); // functional form Circle bar = 20.0; // assignment init. Circle baz ; // uniform init. Circle qux = ; // POD-like cout
foo’s circumference: 62.8319
Преимуществом унифицированной инициализации перед функциональной формой является то, что в отличие от круглых скобок, фигурные нельзя перепутать с объявлением функции, и поэтому могут быть использованы для явного вызова конструктора по умолчанию:
Rectangle rectb; // вызывается конструктор по умолчанию Rectangle rectc(); // объявление функции (конструктор по умолчанию НЕ вызывается) Rectangle rectd<>; // вызывается конструктор по умолчанию
Выбор синтаксиса для вызова конструкторов — это во многом вопрос стиля. Большая часть кода в настоящее время использует функциональную форму, но некоторые наиболее новые руководства по стилю предлагают выбирать унифицированную инициализацию, несмотря на то что она также имеет свои потенциальные проблемы, как наиболее предпочтительную для initializer_list своего типа.
Инициализация членов в конструкторе
Когда конструктор используется для инициализации других членов класса, эти другие члены могут быть инициализированы непосредственно, без использования каких-либо выражений в теле конструктора. Это производится путем вставки перед телом конструктора двоеточия (:) и списка инициализации для членов класса. Например, рассмотрим класс со следующим объявлением:
class Rectangle < int width,height; public: Rectangle(int,int); int area() >;
Конструктор этого класса может быть определен как обычно:
Rectangle::Rectangle (int x, int y)
Однако он также может быть определен с использованием инициализации членов:
Rectangle::Rectangle (int x, int y) : width(x)
Rectangle::Rectangle (int x, int y) : width(x), height(y)
Обратите внимание, как в последнем случае конструктор не делает ничего, кроме инициализации членов, поэтому тело конструктора является пустым.
Для членов фундаментальных типов нет разницы между определенными выше конструкторами, поскольку они не инициализированы по умолчанию, но для объектов (чьим типом является класс), если они не инициализированы после двоеточия, они инициализируются по умолчанию.
Инициализация по умолчанию всех членов класса не всегда может быть удобной: в некоторых случаях этого не нужно (когда член инициализируется в конструкторе), но в некоторых других случаях инициализация по умолчанию может быть невозможной (когда класс не имеет конструктора по умолчанию). В этих случаях члены должны быть инициализированы в списке инициализации членов. Например:
// member initialization #include using namespace std; class Circle < double radius; public: Circle(double r) : radius(r) < >double area() >; class Cylinder < Circle base; double height; public: Cylinder(double r, double h) : base (r), height(h) <>double volume() >; int main ()
foo’s volume: 6283.19
В этом примере класс Cylinder содержит поле, типом которого является другой класс (базовым типом является Circle). По той причине, что объекты класса Circle могут быть инициализированы только с параметром, конструктор класса Cylinder требует вызова конструктора базового класса, и единственный способ сделать это — список инициализации членов.
Эту инициализацию можно реализовать также с помощью синтаксиса унифицированной инициализации, используя фигурные скобки <> вместо круглых ():
Cylinder::Cylinder (double r, double h) : base, height
Указатели на классы
Имеется также возможность создавать указатели на объекты. После объявления класс становится допустимым типом, поэтому он может использоваться как тип, на который указывает указатель. Например:
Rectangle * prect;
это указатель на объект класса Rectangle.
Как и для простых структур данных данных, члены объектов могут доступны непосредственно через указатель путем использования оператора стрелки (->). Вот пример с некоторых возможных комбинаций:
// pointer to classes example #include using namespace std; class Rectangle < int width, height; public: Rectangle(int x, int y) : width(x), height(y) <>int area(void) < return width * height; >>; int main() < Rectangle obj (3, 4); Rectangle * foo, * bar, * baz; foo = &obj; bar = new Rectangle (5, 6); baz = new Rectangle[2] < , >; cout area() area()
Этот пример использует несколько операторов для работы с объектами и указателями (операторы *, , [ ]). Они могут быть интерпретированы как:
выражение | интерпретация |
*x | указатель x |
y | член y объекта, на который указывает x |
(*x).y | член y объекта, на который указывает x (эквивалентно предыдущему) |
x[0] | первый объект, на который указывает x |
x[1] | второй объект, на который указывает x |
x[n] | (n+1)-й объект, на который указывает x |
Большинство этих выражений были представлены в предыдущих разделах. Прежде всего, это раздел о массивах, в котором описан оператор смещения ([ ]), и раздел о простых структурах данных, в котором описан оператор стрелка (->).
Классы, определенные как struct и union
Классы могут быть определены не только при помощи ключевого слова class, но также и при помощи ключевых слов struct и union.
Ключевое слово struct, как правило используемое для объявления простых структур данных, может также быть использовано для объявления классов, имеющих методы, с помощью точно такого же синтаксиса, что и для ключевого слова class. Единственным различием между ними является то, что члены классов, объявленных как struct, имеют открытый доступ по умолчанию, в то время как члены классов, объявленных как class, по умолчанию имеют закрытый доступ. Во всех других отношениях оба ключевых слова эквивалентны в данном контексте.
Концепция объединений отличается от классов, объявленных и как struct, и как class, поскольку объединения хранят только один член данных(поле) одновременно, но они также являются классами и поэтому также могут иметь методы. Объединения имеют открытый доступ по умолчанию.
Источник: pvoid.pro
Классы в С++
Классы и объекты в С++ являются основными концепциями объектно-ориентированного программирования — ООП. Объектно-ориентированное программирование — расширение структурного программирования, в котором основными концепциями являются понятия классов и объектов. Основное отличие языка программирования С++ от С состоит в том, что в С нет классов, а следовательно язык С не поддерживает ООП, в отличие от С++.
Чтобы понять, для чего же в действительности нужны классы, проведём аналогию с каким-нибудь объектом из повседневной жизни, например, с велосипедом. Велосипед — это объект, который был построен согласно чертежам. Так вот, эти самые чертежи играют роль классов в ООП. Таким образом классы — это некоторые описания, схемы, чертежи по которым создаются объекты.
Теперь ясно, что для создания объекта в ООП необходимо сначала составить чертежи, то есть классы. Классы имеют свои функции, которые называются методами класса. Передвижение велосипеда осуществляется за счёт вращения педалей, если рассматривать велосипед с точки зрения ООП, то механизм вращения педалей — это метод класса.
Каждый велосипед имеет свой цвет, вес, различные составляющие — всё это свойства. Причём у каждого созданного объекта свойства могут различаться. Имея один класс, можно создать неограниченно количество объектов (велосипедов), каждый из которых будет обладать одинаковым набором методов, при этом можно не задумываться о внутренней реализации механизма вращения педалей, колёс, срабатывания системы торможения, так как всё это уже будет определено в классе. Разобравшись с назначением класса, дадим ему грамотное определение.
Классы в С++ — это абстракция описывающая методы, свойства, ещё не существующих объектов. Объекты — конкретное представление абстракции, имеющее свои свойства и методы. Созданные объекты на основе одного класса называются экземплярами этого класса. Эти объекты могут иметь различное поведение, свойства, но все равно будут являться объектами одного класса. В ООП существует три основных принципа построения классов:
- Инкапсуляция — это свойство, позволяющее объединить в классе и данные, и методы, работающие с ними и скрыть детали реализации от пользователя.
- Наследование — это свойство, позволяющее создать новый класс-потомок на основе уже существующего, при этом все характеристики класса родителя присваиваются классу-потомку.
- Полиморфизм — свойство классов, позволяющее использовать объекты классов с одинаковым интерфейсом без информации о типе и внутренней структуре объекта.
Каждое свойство построения классов мы рассмотрим подробно по мере необходимости, а пока просто запомните эти три. А теперь вернёмся к классам, для начала рассмотрим структуру объявления классов.
// объявление классов в С++ class /*имя класса*/ < private: /* список свойств и методов для использования внутри класса */ public: /* список методов доступных другим функциям и объектам программы */ protected: /*список средств, доступных при наследовании*/ >;
Объявление класса начинается с зарезервированного ключевого слова class, после которого пишется имя класса.
В фигурных скобочках, строки 3 — 10 объявляется тело класса, причём после закрывающейся скобочки обязательно нужно ставить точку с запятой, строка 10. В теле класса объявляются три метки спецификации доступа, строки 4, 6, 8, после каждой метки нужно обязательно ставить двоеточие.
В строке 4 объявлена метка спецификатора доступа private . Все методы и свойства класса, объявленные после спецификатор доступа private будут доступны только внутри класса. В строке 6 объявлен спецификатор доступа public , все методы и свойства класса, объявленные после спецификатора доступа public будут доступны другим функциям и объектам в программе.
Пока на этом остановимся, спецификатор доступа protected разбирать сейчас не будем, просто запомните, что он есть. При объявлении класса, не обязательно объявлять три спецификатора доступа, и не обязательно их объявлять в таком порядке. Но лучше сразу определиться с порядком объявления спецификаторов доступа, и стараться его придерживаться. Разработаем программу, в которой объявим простейший класс, в котором будет объявлена одна функция, печатающая сообщение.
// classes.cpp: определяет точку входа для консольного приложения. #include «stdafx.h» #include using namespace std; // начало объявления класса class CppStudio // имя класса < public: // спецификатор доступа void message() // функция (метод класса) выводящая сообщение на экран < cout >; // конец объявления класса CppStudio int main(int argc, char* argv[]) < CppStudio objMessage; // объявление объекта objMessage.message(); // вызов функции класса message system(«pause»); return 0; >
В строках 7 — 14 мы определили класс с именем CppStudio.
Имя класса принято начинать с большой буквы, последующие слова в имени также должны начинаться с большой буквы. Такое сочетание букв называют верблюжьим регистром, так как чередование больших и маленьких букв напоминает силуэт верблюда.
В теле класса объявлен спецификатор доступа public , который позволяет вызывать другим функциям методы класса, объявленные после public . Вот именно поэтому в главной функции, в строке 19 мы смогли вызвать функцию message() . В классе CppStudio объявлена всего одна функция, которая не имеет параметров и выводит сообщение на экран, строка 12. Методы класса — это те же функции, только объявлены они внутри класса, поэтому всё что относится к функциям актуально и для методов классов.
Объявление классов выполняется аналогично объявлению функций, то есть класс можно объявлять в отдельном файле или в главном файле, позже посмотрим как это делается. В строке 18 объявлена переменная objMessage типа CppStudio , так вот, переменная objMessage — это объект класса CppStudio . Таким образом, класс является сложным типом данных. После того как объект класса объявлен, можно воспользоваться его методами. Метод всего один — функция message() . Для этого обращаемся к методу объекта objMessage через точку, как показано в строке 19, в результате программа выдаст текстовое сообщение (см. Рисунок 1).
CppStudio.com
website: cppstudio.com theme: Classes and Objects in C + +
Рисунок 1 — Классы в С++
set — функции и get — функции классов
Каждый объект имеет какие-то свои свойства или атрибуты, которые характеризуют его на протяжении всей жизни. Атрибуты объекта хранятся в переменных, объявленных внутри класса, которому принадлежит данный объект. Причём, объявление переменных должно выполняться со спецификатором доступа private . Такие переменные называются элементами данных.
Так как элементы данных объявлены в private , то и доступ к ним могут получить только методы класса, внешний доступ к элементам данных запрещён. Поэтому принято объявлять в классах специальные методы — так называемые set и get функции, с помощью которых можно манипулировать элементами данных. set-функции инициализируют элементы данных, get-функции позволяют просмотреть значения элементов данных. Доработаем класс CppStudio так, чтобы в нём можно было хранить дату в формате дд.мм.гг. Для изменения и просмотра даты реализуем соответственно set и get функции.
// classes.cpp: определяет точку входа для консольного приложения. #include «stdafx.h» #include using namespace std; class CppStudio // имя класса < private: // спецификатор доступа private int day, // день month, // месяц year; // год public: // спецификатор доступа public void message() // функция (метод класса) выводящая сообщение на экран < cout void setDate(int date_day, int date_month, int date_year) // установка даты в формате дд.мм.гг < day = date_day; // инициализация день month = date_month; // инициализация месяц year = date_year; // инициализация год >void getDate() // отобразить текущую дату < cout >; // конец объявления класса CppStudio int main(int argc, char* argv[]) < setlocale(LC_ALL, «rus»); // установка локали int day, month, year; cout > day; cout > month; cout > year; CppStudio objCppstudio; // объявление объекта objCppstudio.message(); // вызов функции класса message objCppstudio.setDate(day, month, year); // инициализация даты objCppstudio.getDate(); // отобразить дату system(«pause»); return 0; >
В определении класса появился новый спецификатор доступа private , строка 9.
Данный спецификатор доступа ограничивает доступ к переменным, которые объявлены после него и до начала спецификатора доступа public , строки 9 — 12. Таким образом к переменным day, month, year , могут получить доступ только методы класса. Функции не принадлежащие классу, не могут обращаться к этим переменным.
Элементы данных или методы класса, объявленные после спецификатора доступа private , но до начала следующего спецификатора доступа называются закрытыми элементами данных и закрытыми методами класса. Следуя принципу наименьших привилегий и принципу хорошего программирования, целесообразно объявлять элементы данных после спецификатора доступа private , а методы класса — после спецификатора доступа public . Тогда, для манипулирования элементами данных, объявляются специальные функции — get и set . В класс CppStudio мы добавили два метода setDate() и getDate() , подробно рассмотрим каждый метод.
Метод setDate() определён с 18 по 23 строки. Как уже ранее упоминалось, set — функции инициализируют элементы данных, поэтому метод setDate() выполняет именно такую функцию. То есть метод setDate() инициализирует переменные day, month, year . Чтобы просмотреть, значения в закрытых элементах данных объявлена функция getDate() , которая возвращает значения из переменных day, month, year в виде даты.На этом определение класса закончено, в main(), как и всегда, создаем объект класса, и через объект вызываем его методы,строки 39 — 41. Если бы элементы данных были объявлены после спецификатора public мы бы смогли к ним обратиться точно также, как и к методам класса. Результат работы программы показан на рисунке 2.
CppStudio.com
Введите текущий день месяц и год! день: 10 месяц: 11 год: 2011 website: cppstudio.comntheme: Classes and Objects in C + + Date: 10.11.2011
Рисунок 2 — Классы в С++
Конструкторы
В предыдущей программе, у класса CppStudio были объявлены элементы данных, которые могут хранить информацию о дате. Когда был создан объект класса, мы сначала вызвали set — функцию, для того, чтобы задать текущую дату (тем самым проинициализировать элементы данных), а потом — вызвали get — функцию и увидели соответствующую дату на экране.
Если бы мы сначала вызвали get — функцию, то вместо даты мы бы увидели какие-то числа — мусор. Так вот, при создании объектов, можно сразу же проинициализировать элементы данных класса, выполняет эту функцию конструктор. Конструктор — специальная функция, которая выполняет начальную инициализацию элементов данных, причём имя конструктора обязательно должно совпадать с именем класса. Важным отличием конструктора от остальных функций является то, что он не возвращает значений вообще никаких, в том числе и void . В любом классе должен быть конструктор,даже если явным образом конструктор не объявлен (как в предыдущем классе), то компилятор предоставляет конструктор по умолчанию, без параметров. Доработаем класс CppStudio , добавив к нему конструктор.
// classes.cpp: определяет точку входа для консольного приложения. #include «stdafx.h» #include using namespace std; class CppStudio // имя класса < private: // спецификатор доступа private int day, // день month, // месяц year; // год public: // спецификатор доступа public CppStudio(int date_day, int date_month, int date_year ) // конструктор класса < setDate(date_day, date_month, date_year); // вызов функции установки даты >void message() // функция (метод класса) выводящая сообщение на экран < cout void setDate(int date_day, int date_month, int date_year) // установка даты в формате дд.мм.гг < day = date_day; // инициализация день month = date_month; // инициализация месяц year = date_year; // инициализация год >void getDate() // отобразить текущую дату < cout >; // конец объявления класса CppStudio int main(int argc, char* argv[]) < CppStudio objCppstudio(11,11,2011); // объявление объекта и инициализация элементов данных objCppstudio.message(); // вызов функции message objCppstudio.getDate(); // отобразить дату system(«pause»); return 0; >
// classes.cpp: определяет точку входа для консольного приложения. #include using namespace std; class CppStudio // имя класса < private: // спецификатор доступа private int day, // день month, // месяц year; // год public: // спецификатор доступа public CppStudio(int date_day, int date_month, int date_year ) // конструктор класса < setDate(date_day, date_month, date_year); // вызов функции установки даты >void message() // функция (метод класса) выводящая сообщение на экран < cout void setDate(int date_day, int date_month, int date_year) // установка даты в формате дд.мм.гг < day = date_day; // инициализация день month = date_month; // инициализация месяц year = date_year; // инициализация год >void getDate() // отобразить текущую дату < cout >; // конец объявления класса CppStudio int main(int argc, char* argv[]) < CppStudio objCppstudio(11,11,2011); // объявление объекта и инициализация элементов данных objCppstudio.message(); // вызов функции message objCppstudio.getDate(); // отобразить дату return 0; >
Конструктор объявлен в строках 13 — 16. Конструктор имеет три параметра, через которые он получает информацию о дате, в теле конструктора вызывается set — функция для установки даты.
Можно было реализовать начальную инициализацию элементов данных класса и без set — функции, но так как эта функция была предусмотрена, то правильнее будет использовать именно эту функцию, строка 15. В строке 35 объявляем объект класса, причём после имени объекта в круглых скобочках передаём три аргумента. Вот так с помощью конструктора выполняется начальная инициализация элементов данных (см. Рисунок 3).
CppStudio.com
website: cppstudio.com theme: Classes and Objects in C + + date: 11.11.2011
Рисунок 3 — Классы в С++
Объявление класса в отдельном файле
До сих пор объявление класса выполнялось в файле с главной функцией и всё работало. Предположим, необходимо написать какую-то программу, для этого необходимо воспользоваться классом CppStudio — разработанный ранее нами класс. Чтобы воспользоваться этим классом, необходимо подключить файл, в котором он объявлен.
Как мы уже говорили, подключение файлов выполняется с помощью препроцессорной директивы #include . Но даже, если мы сможем подключить файл с классом, появится новая проблема — так как в файле с классом уже есть функция main() , то при построении проекта компилятор выдаст ошибку. Суть ошибки: «В проекте найдено несколько main() — функций.» Именно поэтому класс необходимо объявлять в отдельном файле, чтобы его можно было неоднократно использовать. Ранее мы объявляли в отдельном файле функции, таким же образом размещается класс в отдельном файле. Для этого необходимо выполнить 3 шага:
- добавить в проект заголовочный файл *.h ;
- в заголовочном файле объявить пользовательский класс, в нашем случае — CppStudio ;
- подключить заголовочный файл к программе, в нашем случае — #include «CppStudio.h» .
?В зависимости от среды разработки, способы добавления файлов в проект могут отличаться, но суть задачи от этого не меняется. В MVS2010 заголовочный файл можно добавить, вызвав контекстное меню(клик правой кнопкой мыши) в «обозревателе решений«, выбрав пункт «создать новый элемент«. В появившемся диалоговом окне выбираем нужный нам тип файла — это *.h и заполняем поле «Имя файла«. Как и прежде, имя выбираем осмысленное, как правило такое же как и имя класса. Теперь к нашему проекту добавлен новый заголовочный файл — CppStudio.h .
В только что созданном заголовочном файле объявляем класс и, если необходимо, подключаем дополнительные заголовочные. Вот, что должно было получиться:
// заголовочный файл CppStudio.h #include using namespace std; // объявление класса class CppStudio // имя класса < private: // спецификатор доступа private int day, // день month, // месяц year; // год public: // спецификатор доступа public CppStudio(int date_day, int date_month, int date_year ) // конструктор класса < setDate(date_day, date_month, date_year); // вызов функции установки даты >void message() // функция (метод класса) выводящая сообщение на экран < cout void setDate(int date_day, int date_month, int date_year) // установка даты в формате дд.мм.гг < day = date_day; // инициализация день month = date_month; // инициализация месяц year = date_year; // инициализация год >void getDate() // отобразить текущую дату < cout >; // конец объявления класса CppStudio
Чтобы главная функция увидела созданный нами класс и смогла его использовать, необходимо включить определение класса в исполняемом файле, с функцией main() . Делается это так:
// classes.cpp: определяет точку входа для консольного приложения. #include «stdafx.h» // подключаем класс CppStudio #include «CppStudio.h» int main(int argc, char*argv[]) < CppStudio objCppstudio(11,11,2011); // объявление объекта и инициализвция элементов данных objCppstudio.message(); // вызов функции message objCppstudio.getDate(); // отобразить дату system(«pause»); return 0; >
Источник: cppstudio.com
Классы в C++: руководство для начинающих!
Всем привет! Объекты очень важная вещь в программировании, которая может облегчить решения многих задач. Например нужно вести дневник пользователя: год рождения, имя, фамилия, местожительство, все это можно продолжать еще очень долго. Поэтому, как и другие языки программирования C++ обзавелся — классами.
- Что такое класс
- ООП в программировании
- Доступы public и private
- Карточка работника
- Массив объектов
- Отделение методов от логики
- Инициализация объектов с помощью указателей
- Конструктор и деструктор
Как создать класс
Чтобы объявить класс нужно использовать данную конструкцию:
Обычно прописывают с заглавной буквы. Также в конце обязательно должна присутствовать точка с запятой ( ; ).
Что такое класс
Это абстрактный тип данных. Он сочетает в себе два функционала:
- Первая — это структура, в которой можно хранить различные типы данных: массивы, переменные, функции.
- Вторая — возможность пользоваться объектно-ориентированным программированием (ООП — об этом ниже).
Создав класс можно создать его экземпляр — объект. Объект — это функционирующий прототип класса, которому можно задавать свойства и вызывать методы.
У каждого вами созданного класса могут быть свойства и методы. Свойства — это все что может хранить информацию, которую вы потом можете заполнять (переменные, массивы и т.д.).
Так свойства класса Worker (рабочий) может иметь — имя, производительность (полезность работы) за 6 месяцев, среднюю производительность.
class Worker <
public : // об этом ниже
string name ; // имя
// производительность в течении 6 месяцев
int academic_performance [ 6 ] ;
// средняя производительность
int avarage_AP ;
Методы — это обычные функции, в функционале которых можно использовать свойства.
class Worker <
public : // об этом ниже
// функция для вычисления средней производительности
void discover_avarage_AP ( ) <
double answer = 0 ;
for ( int i = 0 ; i < 6 ; i ++ ) <
answer += academic_performance [ i ] ;
avarage_AP = answer / 6 ; // вычисляем с.п.
string name ; // имя
// производительность в течении 6 месяцев
int academic_performance [ 6 ] ;
// средняя успеваемость
int avarage_AP ;
Чтобы обратится к свойствам и методам класса нужно перед названием имени свойства поставить точку . .
Что такое ООП
Раньше программистам приходилось весь функционал программы записывать в одном файле. Что в будущем неизбежно приводило к путанице из-за нескольких сотен и даже тысяч строк. А с приходом классов появилась возможность отделять любую часть программы в отдельный файл.
Например один файл отвечает за инициализацию введенных данных, другой за считывание производительности. Таким образом стала возможным структурировать программу.
В ООП входит такие свойства:
- Инкапсуляция — это возможность задавать разную область видимости определенной части класса .
- Наследование — это свойство создавать новый класс на базе старого. Такие классы называют потомками, например, есть класс магазин , на базе которого можно создать потомки продуктовый_магазин , магазин_одежды (не обращайте внимание, что название на русском языке).
- Полиморфизм — возможность создать объекты с одинаковым интерфейсом, но с разной их реализацией. Например, есть три класса треугольник , круг и квадрат . У каждого из них есть метод SquarePlis() , который вычисляет площадь фигуры. Но для каждого класса функция реализована по-разному.
Источник: codelessons.ru