|
Программирование >> Арифметические и логические операции
Например: printf ( hello, world ); printf ( a=%d b=%d ,a,b); printf ( string=%s ,st); Однако, она всегда должна иметь своим первым параметром char*. В качестве другого примера, float fa[17], *afp[17]; описывает массив чисел с плавающей точкой и массив указателей на числа с плавающей точкой. И, наконец, static int x3d[3][5][7]; описывает массив целых, размером 3x6x7. Совсем подробно: ♦ x3d является массивом из трех элементов; ♦ каждый из элементов является массивом из пяти элементов; ♦ каждый из последних элементов является массивом из семи целых. Появление каждого из выражений x3d, x3d[i], x3d[i]U], x3d[i]U][k] может быть приемлемо. Первые три имеют тип массив , последний имеет тип int. Глава 17. Описания классов Класс специфицирует тип. Его имя становится typedef-имя, которое может быть использовано даже внутри самого спецификатора класса. Объекты класса состоят из последовательности членов. Синтаксис: заголовок класса { список членов opt } заголовок класса { список членов opt public : список членов opt } Где заголовок класса: аrреr идентификатор opt Где идентификатор opt: public opt typedef-имя А агрег может иметь вид: ♦ class ♦ struct ♦ union Структура является классом, все члены которого общие. Объединение является классом, содержащим в каждый момент только один член. Список членов может описывать члены вида: данные, функция, класс, определение типа, перечисление и поле. Список членов может также содержать описания, регулирующие видимость имен членов. Синтаксис: описание члена список членов opt Описание члена: спецификаторы описания opt описатель члена; Описатель члена: описатель идентификатор opt : константное выражение Члены, являющиеся классовыми объектами, должны быть объектами предварительно полностью описанных классов. В частности, класс cl не может содержать объект класса cl, но он может содержать указатель на объект класса cl. Имена объектов в различных классах не конфликтуют между собой и с обычными переменными. Вот простой пример описания структуры: struct tnode char tword[20]; int count; tnode *left; tnode *right; содержащей массив из 20 символов, целое и два указателя на такие же структуры. Если было дано такое описание, то описание tnode s, *sp описывает s как структуру данного сорта и sp как указатель на структуру данного сорта. При наличии этих описаний выражение sp->count ссылается на поле count структуры, на которую указывает sp; s.left ссылается на указатель левого поддерева структуры s; s.right->tword[0] ссылается на первый символ члена tword правого поддерева структуры s. Статические члены Член-данные класса может быть static; члены-функции не могут. Члены не могут быть auto, register или extern. Есть единственная копия статического члена, совместно используемая всеми членами класса в программе. На статический член mem класса cl можно ссылаться cl:mem, то есть без ссылки на объект. Он существует, даже если не было создано ни одного объекта класса cl. Функции-члены Функция, описанная как член, (без спецификатора friend) называется функцией членом и вызывается с помощью синтаксиса члена класса. Например: struct tnode char tword[20]; int count; tnode *left; tnode *right; void set (char* w,tnode* l,tnode* r); tnode n1, n2; n1.set ( asdf ,&n2,0); n2.set ( ghjk ,0,0); Определение функции члена рассматривается как находящееся в области видимости ее класса. Это значит, что она может непосредственно использовать имена ее класса. Если определение функции члена на- ходится вне описания класса, то имя функции члена должно быть уточнено именем класса с помощью записи typedef-имя . простое оп имя Например: void tnode.set (char* w,tnode* l,tnode* r) count = strlen (w); if (sizeof (tword) <= count) error ( tnode string too long ); strcpy (tword,w); left = l; right = r; Имя функции tnode.set определяет то, что множество функций является членом класса tnode. Это позволяет использовать имена членов word, count, left и right. В функции члене имя члена ссылается на объект, для которого была вызвана функция. Так, в вызове n1.set(... ) tword ссылается на n1.tword, а в вызове n2.set(...) он ссылается на n2.tword. В этом примере предполагается, что функции strlen, error и strcpy описаны где-то в другом месте как внешние функции. В члене функции ключевое слово this указывает на объект, для которого вызвана функция. Типом this в функции, которая является членом класса cl, является cl*. Если mem - член класса cl, то mem и this->mem - синонимы в функции члене класса cl (если mem не был использован в качестве имени локальной переменной в промежуточной области видимости). Функция член может быть определена в описании класса. Помещение определения функции члена в описание класса является кратким видом записи описания ее в описании класса и затем определения ее как inline сразу после описания класса. Например: int b; struct x int f () { return b; } int f () { return b; } int b; означает int b; struct x int f (); int b; inline x.f () { return b; } Для функций членов не нужно использование спецификатора overload: если имя описывается как означающее несколько имен в классе, то оно перегружено. Применение операции получения адреса к функциям членам допустимо. Тип параметра результирующей функции указатель на есть (...), то есть, неизвестен. Любое использование его является зависимым от реализации, поскольку способ инициализации указателя для вызова функции члена не определен. Производные классы В конструкции аrреr идентификатор:pub1ic opt typedef-имя typedef-имя должно означать ранее описанный класс, называемый базовым классом для класса, подлежащего описанию. Говорится, что последний выводится из предшествующего. На члены базового класса можно ссылаться, как если бы они были членами производного класса, за исключением тех случаев, когда имя базового члена было переопределено в производном классе; в этом случае для ссылки на скрытое имя может использоваться такая запись: typedef-имя :: идентификатор Например: struct base int a; int b; struct derived : public base int b; int c; derived d; d.a = 1; d.base::b = 2; d.b = 3; d.c = 4; осуществляет присваивание четырем членам d. Производный тип сам может использоваться как базовый. Виртуальные функции Если базовый класс base содержит (виртуальную) virtual функцию vf, а производный класс derived также содержит функцию vf, то вызов vf для объекта класса derived вызывает derived::vf. Например: struct base virtual void vf (); void f (); struct derived : public base void vf (); void f (); derived d; base* bp = &d; bp->vf (); bp->f (); Вызовы вызывают, соответственно, derived::vf и base::f для объекта класса derived, именованного d. Так что интерпретация вызова виртуальной функции зависит от типа объекта, для которого она вызвана, в то время как интерпретация вызова невиртуальной функции зависит только от типа указателя, обозначающего объект. Из этого следует, что тип объектов классов с виртуальными функциями и объектов классов, выведенных из таких классов, могут быть определены во время выполнения. Если производный класс имеет член с тем же именем, что и у виртуальной функции в базовом классе, то оба члена должны иметь одинаковый тип. Виртуальная функция не может быть другом (friend). Функция f в классе, выведенном из класса, который имеет виртуальную функцию f, сама рассматривается как виртуальная. Виртуальная
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |