Выбрать главу

_cursor += len - 1;

}

void Screen::set( char ch )

{

if ( ch == '\0' )

cerr "Screen: warning: "

"null character (ignored).\n";

else _screen[_cursor] = ch;

}

В реализации класса Screen мы предполагаем, что объект Screen не содержит двоичных нулей. По этой причине set() не позволяет записать на экран нуль.

Представленные до сих пор функции-члены были открытыми, их можно вызывать из любого места программы, а закрытые вызываются только из других функций-членов (или друзей) класса, но не из программы, обеспечивая поддержку другим операциям в реализации абстракции класса. Примером может служить функция-член remainingSpace класса Screen(), использованная в set(const string&).

class Screen {

public:

// объявления других функций-членов не изменяются

private:

inline int remainingSpace();

};

remainingSpace() сообщает, сколько места осталось на экране:

inline int Screen::remainingSpace()

{

int sz = _width * _height;

return ( sz - _cursor );

}

(Детально защищенные функции-члены будут рассмотрены в главе 17.)

Следующая программа предназначена для тестирования описанных к настоящему моменту функций-членов:

#include "Screen.h"

#include iostream

int main() {

Screen sobj(3,3); // конструктор определен в разделе 13.3.4

string init("abcdefghi");

cout "Screen Object ( "

sobj.height() ", "

sobj.width() " )\n\n";

// Задать содержимое экрана

string::size_type initpos = 0;

for ( int ix = 1; ix = sobj.width(); ++ix )

for ( int iy = 1; iy = sobj.height(); ++iy )

{

sobj.move( ix, iy );

sobj.set( init[ initpos++ ] );

}

// Напечатать содержимое экрана

for ( int ix = 1; ix = sobj.width(); ++ix )

{

for ( int iy = 1; iy = sobj.height(); ++iy )

cout sobj.get( ix, iy );

cout "\n";

}

return 0;

}

Откомпилировав и запустив эту программу, мы получим следующее:

Screen Object ( 3, 3 )

abc

def

ghi

13.3.4. Специальные функции-члены

Существует специальная категория функций-членов, отвечающих за такие действия с объектами, как инициализация, присваивание, управление памятью, преобразование типов и уничтожение. Такие функции называются конструкторами. Они вызываются компилятором неявно каждый раз, когда объект класса определяется или создается оператором new. В объявлении конструктора его имя совпадает с именем класса. Вот, например, объявление конструктора класса Screen, в котором заданы значения по умолчанию для параметров hi, wid и bkground:

class Screen {

public:

Screen( int hi = 8, int wid = 40, char bkground = '#');

// объявления других функций-членов не изменяются

};

Определение конструктора класса Screen выглядит так:

Screen::Screen( int hi, int wid, char bk ) :

_height( hi ), // инициализировать _height значением hi

_width( wid ), // инициализировать _width значением wid

_cursor ( 0 ), // инициализировать _cursor нулем

_screen( hi * wid, bk ) // размер экрана равен hi * wid

// все позиции инициализируются

// символом '#'

{ // вся работа проделана в списке инициализации членов

// этот список обсуждается в разделе 14.5

}

Каждый объявленный объект класса Screen автоматически инициализируется конструктором:

Screen s1; // Screen(8,40,'#')

Screen *ps = new Screen( 20 ); // Screen(20,40,'#')

int main() {

Screen s(24,80,'*'); // Screen(24,80,'*')

// ...

}

(В главе 14 конструкторы, деструкторы и операторы присваивания рассматриваются более подробно. В главе 15 обсуждаются конвертеры и функции управления памятью.)

13.3.5. Функции-члены со спецификаторами const и volatile

Любая попытка модифицировать константный объект из программы обычно помечается компилятором как ошибка. Например:

const char blank = ' ';

blank = '\n'; // ошибка

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

const Screen blankScreen;

blankScreen.display(); // читает объект класса

blankScreen.set( '*' ); // ошибка: модифицирует объект класса

Проектировщик класса может указать, какие функции-члены не модифицируют объект, объявив их константными с помощью спецификатора const: