Почему два ключевых слова несут одинаковую смысловую нагрузку

Вы, вероятно, удивлены тем, что два различных ключевых слова создают практически идентичные объявления. Так сложилось исторически. Язык C++ строился как расширение С. В языке С были структуры, но эти структуры не имели методов класса. Создатель C++, Бьерн Страуструп, опирался на структуры, но заменил имя типа данных struct типом class, чтобы тем самым заявить о новых расширенных функциональных возможностях этого нового образования.

Рекомендуется: Используйте спецификатор const везде, где это возможно. Убедитесь, что вам полностью понятны классы, прежде чем переходить к следующему занятию.

Помещайте объявление класса в файл с расширением .hpp, а его выполнение — в файл с расширением .cpp.

Резюме

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

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

Члены класса — как данные, так и функции — могут быть открытыми и закрытыми. Открытые члены доступны для любой части программы, а закрытые — только для функций-членов данного класса.

Хорошим стилем программирования считается вынесение интерфейса, или объявления класса, в файл заголовка, который обычно имеет расширение .hpp. Выполнение класса записывается в файл с расширением .cpp.

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

Вопросы и ответы

Как определяется размер объекта класса?

Размер объекта класса в памяти определяется суммой размеров переменных- членов. Методы класса не занимают место в области памяти, выделенной для объекта.

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

Если объявить класс Cat с закрытым членом itsAge, а затем определить два объекта класса Cat с именами Frisky и Boots, то может ли объект Boots получить доступ к переменной-члену itsAge объекта Frisky?

Да. Закрытые данные доступны для функций-членов класса, и различные экземпляры одного класса могут обращаться к данным друг друга. Иными словами, если Frisky и Boots являются экземплярами класса Cat, то функции-члены объекта Frisky могут получить доступ как к своим данным (данным объекта Frisky), так и к данным объекта Boots.

Почему не следует делать все данные-члены открытыми?

Объявление данных-членов закрытыми позволяет клиенту класса использовать данные, не волнуясь о том, как они хранятся или вычисляются. Например, если класс Cat имеет метод GetAge(), клиенты класса Cat могут возвратить значение возраста кошки (объекта класса Cat), не заботясь о том, хранится ли оно в какой-нибудь переменной-члене определенного типа или вычисляется по запросу.

Если применение функции const для изменения класса вызывает ошибку компилятора, то почему бы просто не использовать ключевое слово const и тем самым гарантированно избежать сообщений об ошибках?

Если ваша функция-член логически не должна изменять класс, то использование ключевого слова const — прекрасный способ заручиться поддержкой компилятора при отыскании случайных ошибок, Например, у функции GetAge() нет видимых причин для изменения класса Cat, но в выполнении класса может присутствовать следующая строка:

if (itsAge = 100) cout << "Ого Тебе уже сто лет\n";

Объявление функции GetAge() с использованием ключевого слова const заставило бы компилятор обнаружить ошибку. Вы ведь имели в виду сравнение значения переменной itsAge с числом 100, а вместо этого случайно выполнили операцию присвоения числа 100 переменной itsAge. Поскольку это присвоение изменяет класс, а вы (с помощью ключевого слова const) заявили, что этот метод не будет изменять класс, компилятор смог найти ошибку.

Ошибки такого рода, как правило, трудно найти простым просмотром текста программы. Мы часто видим то, что хотим увидеть. Гораздо опаснее, если на первый взгляд вам покажется, что программа работает правильно (даже после установки такого странного значения), но рано или поздно эта неприятность превратится в проблему.

Существует ли резон использовать структуры в программах на C++?

Многие программисты используют ключевое слово struct для классов, которые не имеют функций. Можно расценивать это как ностальгию по устаревшим структурам языка С, которые не могли иметь функций. Лично я считаю это ненужным и даже плохим стилем программирования. Ведь если сегодня данной структуре не нужны методы, то не исключено, что они могут понадобиться ей завтра. И тогда вам придется либо заменять этот тип классом, либо нарушать свое же правило и работать со структурой, которая "не брезгует" присутствием в ней методов.

Коллоквиум

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

Контрольные вопросы

1. Что представляет собой оператор прямого доступа и для чего он используется?

2. Что резервирует память — объявление или определение?

3. Объявление класса является его интерфейсом или выполнением?

4. Какова разница между открытыми (public) и закрытыми (private) данными- членами?

5. Могут ли функции-члены быть закрытыми?

6. Могут ли переменные-члены быть открытыми?

7. Если объявить два объекта класса Cat, могут ли они иметь различные значения их переменных-членов itsAge?

8. Нужно ли объявления класса завершать точкой с запятой? А определения методов класса?

9. Как бы выглядел заголовок функции-члена Meow класса Cat, которая не принимает никаких параметров и возвращает значение типа void?

10. Какая функция вызывается для выполнения инициализации класса?

Упражнения

1. Напишите программу, которая объявляет класс с именем Employee (Служащие) с такими переменными-членами: age (возраст), yearsOfService (стаж работы) и Salary (зарплата).

2. Перепишите класс Employee, чтобы сделать данные-члены закрытыми и обеспечить открытые методы доступа для чтения и установки всех данных-членов.

3. Напишите программу с использованием класса Employee, которая создает два объекта класса Employee; устанавливает данные-члены age, YearsOfService и Salary, а затем выводит их значения.

4. На основе программы из упражнения 3 создайте метод класса Employee, который сообщает, сколько тысяч долларов зарабатывает служащий, округляя ответ до 1 000 долларов.

5. Измените класс Employee так, чтобы можно было инициализировать данные-члены age, YearsOfService и Salary в процессе "создания" служащего.

6. Жучки: что неправильно в следующем объявлении?

class Square

{

public:

int Side;

}

7. Жучки: что весьма полезное отсутствует в следующем объявлении класса?

class Cat

{

int GetAge() const;

private:

int itsAge;

};

8. Жучки: какие три ошибки обнаружит компилятор в этом коде?

class TV

{

public:

void SetStation(int Station);

int GetStation() const;

private:

int itsStation;

};

main()

{

TV myTV;

myTV.itsStation = 9;

TV.SetStation(10);

TV myOtherTv(2);

}

День 7-й. Циклы

Структура любой программы состоит из комбинации множества ветвлений и циклов. На четвертом занятии вы научились организовывать ветвление программы с помощью оператора if. Сегодня вы узнаете:

• Что такое циклы и как они используются

• Каковы методы организации циклов

• Как избежать чрезмерной вложенности конструкций if/else

Организация циклов

Для решения ряда задач часто требуется многократное выполнение одних и тех же действий. На практике это реализуется с помощью рекурсивных (см. занятие 5) или итеративных алгоритмов. Суть итеративного процесса заключается в повторении последовательности операций нужное количество раз.

История оператора goto

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

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

Листинг 7.1. Организация цикла с помощью оператора goto

1: // Листинг 7.1.

2: // Организация цикла с помощью goto

3:

4: #include <iostream.h>

5:

6: int main()

7: {

8: int counter = 0; // инициализация счетчика

9: loop: counter++; // начало цикла

10: cout.<< "counter: " << counter << "\n";

11: if (counter < 5) // проверка значения

12: goto loop; // возвращение к началу

13:

14: cout << "Complete. Counter: " << counter << ".\n";

15: return 0;

16: }

Результат:

counter: 1

counter: 2

countor: 3

counter: 4

counter: 5

Complete. Counter: 5.

Анализ: В строке 8 переменная counter инициализируется нулевым значением. Метка loop: в строке 9 показывает начало цикла. На каждой итерации значение counter yвeличивaeтcя на единицу и выводится на экран. В строке 11 выполняется проверка значения переменной counter. Если оно меньше пяти, значит условие выполняется и управление передается оператору goto, в результате чего осуществляется переход на строку 9. Итеративный процесс выполняется до тех пор, пока значение переменной counter не достигнет пяти. После этого программа выходит за пределы цикла и на экран выводится окончательный результат.

Наши рекомендации