список_членов: описание_члена список_членов opt описание_члена: спецификаторы_описания 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 (#8.5.10)) называется функцией членом и вызывается с исползованием синтаксиса члена класса (#7.1). Например:
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», amp;n2,0); n2.set («ghjk»,0,0);
Определение функции члена рассматривается как находящеся в области видимости ее класса. Это значит, что она может непосредственно использовать имена ее класса. Если определние функции члена лексически находится вне описания класса, то имя функции члена должно быть уточнено именем класса с пмощью операции ::. Определения функций обсуждаются в #10.
Например:
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 определяет то, что функция set является членом класса tnode и принадлежит его области видисости. Имна членов tword, count, left и right относятся к объекту, для которого была вызвана функция. Так, в вызове n1.set(«abc»,0,0) tword ссылается на n1.tword, а в вызове n2. set(«def»,0,0) оно ссылается на n2.tword. Предполагается, что функции strlen, error и strcpy описаны где-то в другом месте, см. #10.
В функции члене ключевое слово this является указателем на объект, для которого вызвана функция.
Функция член может быть определена (#10) в описании класса, и в этом случак она является inline (#8.1). Например:
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; *)
Применение операции получения адреса к функциям членам допустимо. Однако, тип параметра результирующего указателя на функцию неопределн, поэтому любое использование его является зависимым от реализации.
В конструкции
сост идентификатор : public opt typedef-имя
typedef-имя должно означать ранее описанный класс, назваемый базовым классом для описываемого класса. Говорится, что последний выводится из предшествующего (является проиводным от него). По поводу смысла public см. #8.5.9. На члены базового класса можно ссылаться так, как если бы они были членами производного класса, за исключением тех случаев, кода имя базового члена было переопределено в производном класе; в этом случае для ссылки на скрытое имя можно использвать операцию :: (#7.1). Производный класс сам может использоваться в качестве базового класса. Невозможно стристь производные от union (#8.5.13). Указатель на производный класс может неявно преобразовываться в указатель на открытый
базовый класс (#6.7).
Для объектов класса, производного от класса, для которго была определена operator= (#8.5.11), присваивание неявно не определено (#7.14 и #8.5)
Например:
class base (* int a, b; *);
class derived : public base (* int b, c; *);
derived d;
d.a = 1; d.base::b = 2; d.b = 3; d.c = 4;
осуществляет присваивание четырем членам d.
8.5.4 Виртуальные Функции
Если базовый класс base содержит virtual (виртуальную) (#8.1) функцию vf, а производный класс derived также содержит функцию vf, то обе функции должны иметь один и тот же тип, и вызов vf для объекта класса derived вызывает derived::vf. Например:
Читать дальше