Опубликован: 07.03.2015 | Уровень: для всех | Доступ: свободно | ВУЗ: Компания ALT Linux
Лекция 10:

Объектно-ориентированное программирование

10.2 Классы и объекты в C++

Хотя C++ и не первая попытка создать объектно-ориентированную версию языка С, среди попыток такого рода он оказался наиболее успешным. Очевидно, одна из причин успешности — то, каким образом объектная парадигма была встроена в синтаксис языка.

Ранние версии C++ были созданы в начале 1980-х Бьёрном Страуструпом для собственных нужд (в качестве универсального языка программирования, удобного для компьютерного моделирования). В создаваемый язык были заложены следующие основные принципы:

  • поддержка различных стилей программирования, включая процедурный и объектно-ориентированный подходы;
  • предоставление программисту полной свободы выбора — в т. ч. реализовать программные решения, которые могут казаться концептуально неверными;
  • сохранение обратной совместимости с языком С, чтобы программист мог использовать только те дополнительные возможности C++, которые он сочтёт нужным, или не использовать их вовсе.

Эти принципы заслужили высокую оценку программистов-практиков. В результате на текущий момент C++ является одним из наиболее распространённых языков программирования — как системного, так и прикладного.

10.2.1 Реализация ООП в C++. Классы и структуры

Синтаксис описания класса во многом копирует синтаксис описания структуры. В простейшем случае класс описывается так:

class имя_класса
{
	закрытые члены класса
	public :
	открытые члены класса
};

Как и при объявлении структуры, имя_класса становится новым именем типа данных, которое можно использовать для объявления переменных (объектов класса) [5, 6]. Членами класса будут переменные и функции, объявленные внутри класса. Функции-члены класса называют методами этого класса, а переменныечлены класса называют свойствами класса.

В C++ понятия ООП используются следующим образом 5, 6]:

  • "класс": пользовательский тип данных, во многом аналогичный структуре;
  • "объект класса" или "переменная-экземпляр класса": переменная, в описании которой какой-то класс указан в качестве типа данных;
  • "свойство" или "переменная-член класса": переменная, объявленная внутри класса (как поле внутри структуры); на практике чаще говорят не о свойстве класса, а о свойстве объекта, так как для конкретных объектов переменные — члены класса обладают конкретными значениями и потому имеют конкретный смысл.
  • "метод": функция, объявленная внутри класса.

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

Открытых и закрытых секций в классе может быть несколько, и они могут произвольно чередоваться. При необходимости обозначить очередную закрытую секцию, её начало обозначается ключевым словом private.

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

  • в структурах вместо ключевого слова class пишется ключевое слово struct;
  • в структурах по умолчанию все члены являются отрытыми (иначе перестали бы работать программы, написанные на С).

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

class spatial_vector
{
public :
	double abs ( );
private :
	double x, y, z;
};
struct spatial_vector
{
	double abs ( );
private :
	double x, y, z;
};

Добавив в структуру или в класс какой-нибудь метод, программист может потом вызвать этот метод для конкретного объекта. Обращение к содержимому объекта выполняется так же, как к содержимому структурной переменной: с использованием операции "." (либо операции "->", если нужно обратиться по указателю на объект).

main ( )
{
	spatial_vector a,b;
	double d;
	.......
	d = a.abs ( );
}

Очевидно, что функция abs(), объявленная в классе spatial_vector, возвращает абсолютное значение вектора. Однако для того, чтобы программа скомпилировалась, после объявления функцию abs() нужно ещё определить (т. е. написать тело этой функции). Определение метода выполняется так же, как обычной функции, только в имени метода нужно указать, что он принадлежит конкретному классу. Для этого используется оператор расширения области видимости "::". Имя класса записывается перед именем функции, отделённое двойным двоеточием. Например, в следующем примере мы объявим всё тот же класс spatial_vector с двумя методами (установить значения координат вектора и посчитать его модуль) и опишем эти методы:

#include <iostream>
#include <math.h>
using namespace std;
class spatial_vector
{
	double x, y, z;
public :
	void set ( double a,double b,double c );
	double abs ( );
};
void spatial_vector::set ( double a,double b,double c )
{
	x=a;y=b;z=c;
}
double spatial_vector::abs ( )
{
	return sqrt ( x*x + y*y + z*z );
}
main ( )
{
	spatial_vector a;
	a.set ( 1, 2, 3 );
	cout << a.abs ( ) << endl;
}
Сергей Радыгин
Сергей Радыгин

Символы кириллицы выводит некорректно. Как сделать чтобы выводился читабельный текст на русском языке?

Тип приложения - не Qt,

Qt Creator 4.5.0 основан на Qt 5.10.0. Win7.

 

Юрий Герко
Юрий Герко

Кому удалось собрать пример из раздела 13.2 Компоновка (Layouts)? Если создавать проект по изложенному алгоритму, автоматически не создается  файл mainwindow.cpp. Если создавать этот файл вручную и добавлять в проект, сборка не получается - компилятор сообщает об отсутствии класса MainWindow. Как правильно выполнить пример?