Г. Шилтд - Самоучитель C++ (PDF) (1114887), страница 11
Текст из файла (страница 11)
Это важно для понимания следующего положения: создание указателя на объект не создает объекта, оносоздает только указатель на него.Для передачи адреса объекта ob в переменную р, использовалась инструкция:р = sob;И последнее, в программе показано, как можно получить доступ к членамобъекта с помощью указателя на этот объект.Мы вернемся к обсуждению указателей на объекты в главе 4, когда у вас ужебудет более полное представление о C++.Глава 2. Введение в классы652.5.
Классы, структуры и объединенияКак вы уже заметили, синтаксически класс похож на структуру. Вас, возможно, удивило то, что класс и структура имеют фактически одинаковыесвойства. В C++ определение структуры расширили таким образом, что туда, как и в определение класса, удалось включить функции-члены, в томчисле конструкторы и деструкторы.
Таким образом, единственным отличием между структурой и классом является то, что члены класса, по умолчанию, являются закрытыми, а члены структуры — открытыми. Здесь показанрасширенный синтаксис описания структуры:struct имя типа {// открытые функции и данные — «лены класса.private:// закрытие функция и данные — члены класса} список объектовТаким образом, в соответствии с формальным синтаксисом C++ как структура, так и класс создают новые типы данных. Обратите внимание на введение нового ключевого слова. Им является слово private, которое сообщаеткомпилятору, что следующие за ним члены класса являются закрытыми.В том, что структуры и классы обладают фактически одинаковыми свойствами, имеется кажущаяся избыточность. Те, кто только знакомится с C++,часто удивляются этому дублированию.
При таком взгляде на проблему ужене кажутся необычными рассуждения о том, что ключевое слово class совершенно лишнее.Объяснение этому может быть дано в "строгой" и "мягкой" формах."Строгий" довод состоит в том, что необходимо поддерживать линию на совместимость с С. Стиль задания структур С совершенно допустим и дляпрограмм C++. Поскольку в С все члены структур по умолчанию открыты,это положение также поддерживается и в C++. Кроме этого, посколькукласс синтаксически отличается от структуры, определение класса открытодля развития в направлении, которое в конечном итоге может привести кнесовместимости со взятым из С определением структуры. Если эти два пути разойдутся, то направление, связанное с C++, уже не будет избыточным."Мягким" доводом в пользу наличия двух сходных конструкций стало отсутствие какого-либо ущерба от расширения определения структуры в C++таким образом, что в нее стало возможным включение функций-членов.Хотя структуры имеют схожие с классами возможности, большинство программистов ограничивают использование структур взятыми из С формами ине применяют их для задания функций-членов.
Для задания объекта, содержащего данные и код, эти программисты обычно указывают ключевое словоclass. Однако все это относится к стилистике и является предметом вашегособственного выбора. (Далее в книге за исключением текущего раздела с66Самоучитель C++помощью ключевого слова struct задаются объекты, которые не имеютфункций-членов.)Если вы нашли интересной связь между классами и структурами, вас заинтересует и следующее необычное свойство C++: объединения и классы вэтом языке столь же близки! В C++ объединение также представляет собойтип класса, в котором функции и данные могут содержаться в качестве егочленов.
Объединение похоже на структуру тем, что в нем по умолчанию всечлены открыты до тех пор, пока не указан спецификатор private. Главное жев том, что в C++ все данные, которые являются членами объединения, находятся в одной и той же области памяти (точно так же, как и в С). Объединения могут содержать конструкторы и деструкторы. Объединения C++совместимы с объединениями С.Если в отношениях между структурами и классами существует, на первыйвзгляд, некоторая избыточность, то об объединениях этого сказать нельзя. Вобъектно-ориентированном языке важна поддержка инкапсуляции. Поэтомуспособность объединений связывать воедино программу и данные позволяетсоздавать такие типы классов, в которых все данные находятся в общей области памяти.
Это именно то, чего нельзя сделать с помощью классов.Применительно к C++ имеется несколько ограничений, накладываемых наиспользование объединений. Во-первых, они не могут наследовать какой быто ни было класс и не могут быть базовым классом для любого другогокласса. Объединения не могут иметь статических членов. Они также недолжны содержать объектов с конструктором или деструктором, хотя самипо себе объединения могут иметь конструкторы и деструкторы.В C++ имеется особый тип объединения -- это анонимное объединение(anonymous union).
Анонимное объединение не имеет имени типа и следовательно нельзя объявить переменную такого типа. Вместо этого анонимноеобъединение просто сообщает компилятору, что все его члены будут находиться в одной и той же области памяти. Во всех остальных отношенияхчлены объединения действуют и обрабатываются как самые обычные переменные. То есть, доступ к членам анонимного объединения осуществляетсянепосредственно, без использования оператора точка (.). Например, рассмотрим следующий фрагмент:union { // анонимное объединениеint i;char c h [ 4 ] ;};// непосредственный доступ к переменным i и chi = 10;ch[0] = 'X';Обратите внимание на то, что, поскольку переменные i и ch не являютсячастью какого бы то ни было объекта, доступ к ним осуществляется непосредственно.
Тем не менее они находятся в одной и той же области памяти.Глава 2. Введение в классы67Смысл анонимных объединений в том и состоит, что они обеспечиваютпростой способ сообщить компилятору о необходимости разместить однуили несколько переменных в одной и той же области памяти. Исключая этуособенность, члены анонимного объединения больше ничем не отличаютсяот других переменных.Все те ограничения, которые накладываются на использование обычныхобъединений, применимы и к анонимным объединениям.
Кроме этого кним добавлено еще несколько. Глобальное анонимное объединение должнобыть объявлено как статическое. Анонимное объединение не может содержать закрытых членов. Имена членов анонимного объединения не должныконфликтовать с другими идентификаторами той же области видимости.1. Ниже представлена короткая программа, в которой для создания класса используется ключевое слово struct:# include <iostream>^include <cstring>using namespace std;// использование структуры для определения типа классаstruct st_type {st_type (double b, char *n) ;void show{) ;private:double balance;char name [40] ;st_type: : st_type (double b, char *n){balance = b;strcpy (name, n) ;}void st_type: :show{){cout « "Имя:" « name;cout « ":$" « balance;if (balance < 0.0) cout « "***";cout « "\n";}int main(}{st_typest typeaccl(100.12, "Johnson") ;acc2(-12.34, "Hedricks" )68_СамоучительC++accl.show() ;acc2.show{) ;return 0;Отметьте, что, как уже говорилось, члены структуры по умолчанию являютсяоткрытыми.
Для объявления закрытых членов необходимо использоватьключевое слово private.Кроме этого отметьте существенное отличие между структурами С и структурамиC++. В C++ имя тега становится также и законченным именем типа данных,которое можно использовать для объявления объектов. В С, чтобы имя тега стаюзаконченным именем типа данных, перед ним надо указывать ключевое словоstruct.Ниже представлена только что рассмотренная программа, но вместо структуры здесь используется класс:^include <iostream>ttinclude <cstring>using namespace std;class cl_type (double balance;char name[40];public:cl_type{double b, char *n);void show();cl_type: :cl_type {double b, char *n)(balance = b;strcpyfname, n) ;}void cl_type : : show( )(cout « "Имя:" « name;cout « ":$" « balance;if (balance < 0 .
0 ) cout « "***";cout « "\n";}int{rnainf)cl_typecl_typeaccl ,show() ;acc2.show() ;accl(100.12, "Johnson");acc2(-12.34, "Hedricks")Глава2.Введениевклассы_69return 0;2. Пример использования объединения для побайтного вывода значения типаdouble в двоичном представлении:^include <iostream>using namespace std;union bits (bits (double n) ;void show_bits ( ) ;double d;unsigned char c[sizeof (double)];1;bits: :bits (double n){d = n;void bits : : show_bits { ){int i, j;for( j = sizeof (double) — 1; j >= 0; j — ) {cout « "Двоичное представление байта" « j «for( i = 128; i; i »= 1)if(i & c[ j ]) cout « "1";else cout « "0";cout « "\n";int main{ ){bits оЫЗ.991.829) ;ob.show_bits () ;return 0;Результат работы программыДвоичноеДвоичноеДвоичноеДвоичноеДвоичноепредставлениепредставлениепредставлениепредставлениепредставлениебайтабайтабайтабайтабайта7: 010000006: 100111115: 000111114: 010100003: 1110010170_СамоучительC++Двоичное представление байта 2: 01100000Двоичное представление байта 1: 01000001Двоичное представление байта 0: 100010013.
Структуры и объединения могут иметь конструкторы и деструкторы. В следующем примере класс strtype переделан в структуру. В структуре имеютсяконструктор и деструктор.# include <iostrearn># include <cstring>^include <cstdlib>using namespace std;,struct strtype {strtype (char *ptr) ;~strtype (} ;void show() ;private :char *p;int len;<! #strtype: :strtype (char *ptr){len = strlen(ptr);p = (char *) m a l l o c f l e n + 1) ;if<!p> {cout « "Ошибка вьщеления памяти \п";exit(l) ;strcpy{p, ptr) ;strtype: : -strtype ()(cout « "Освобождение памяти по адресу р\п";free (p) ;1void strtype: : show {}(cout « p « "- длина: " « len;cout « "\n";int main ()strtype si("Это проверка"}, з2("Мне нравится C++");Глава2.Введениевклассы_-71Sl.showl);s2 .
show {) ;return 0;4. В следующей программе для побайтного вывода на экран значения типаdouble используется анонимное объединение. (Предполагается, что длиназначения типа double равна восьми байтам.)// Использование анонимного объединения^include <iostream>using namespace std;int main(}union {unsigned char bytes[8];double value;);int i;value = 8 5 9 3 4 5 . 3 2 4 ;// побайтный вывод значения типа doublef o r ( i = 0 ; i<8; i++)cout « (int) b y t e s [ i j « " ";return 0;Обратите внимание, что доступ к переменным value и bytes осуществляетсятак, как если бы они были не частью объединения, а обычными переменными.