|
Программирование >> Инициализация объектов класса, структура
Screen Object ( 3, 3 ) abc def ghi 13.3.4. Специальные функции-члены Существует специальная категория функций-членов, отвечающих за такие действия с объектами, как инициализация, присваивание, управление памятью, преобразование типов и уничтожение. Такие функции называются конструкторами. Они вызываются компилятором неявно каждый раз, когда объект класса определяется или создается оператором new. В объявлении конструктора его имя совпадает с именем класса. Вот, например, объявление конструктора класса Screen, в котором заданы значения по class Screen { public: Screen( int hi = 8, int wid = 40, char bkground = #); объявления других функций-членов не изменяются умолчанию для параметров hi, wid и bkground: 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 выглядит так: Кажд1й объявленн1й объект класса Screen автоматически инициализируется Screen s1; Screen(8,40,#) Screen *ps = new Screen( 20 ); Screen(20,40,#) int main() { Screen s(24,80,*); Screen(24,80,*) ... конструктором: Откомпилировав и запустив эту программу, м1 получим следующее: const char blank = ; компилятором как ошибка. Например: blank = \n; ошибка Однако объект класса, как правило, не модифицируется программой напрямую. Вместо этого вызывается та или иная открытая функция-член. Чтобы не было покушений на константность объекта, компилятор должен различать безопасные (те, которые не const Screen blankScreen; blankScreen.display(); читает объект класса изменяют объект) и небезопасные (те, которые пытаются это сделать) функции-члены: blankScreen.set( * ); ошибка: модифицирует объект класса Проектировщик класса может указать, какие функции-члены не модифицируют объект, class Screen { public: char get() const { return screen[ cursor]; } ... объявив их константными с помощью спецификатора const: }; Для класса, объявленного как const, могут быть вызваны только те функции-члены, которые также объявлены со спецификатором const. Ключевое слово const помещается между списком параметров и телом функции-члена. Для константной функции-члена, определенной вне тела класса, это слово должно присутствовать как в объявлении, так и в определении: (В главе 14 конструкторы, деструкторы и операторы присваивания рассматриваются более подробно. В главе 15 обсуждаются конвертеры и функции управления памятью.) 13.3.5. Функции-члены со спецификаторами const и volatile Любая попытка модифицировать константный объект из программа: обычно помечается class Screen { public: bool isEal( char ch ) const; ... private: string::size type cursor; string screen; ... bool Screen::isEal( char ch ) const { return ch == screen[ cursor]; Запрещено объявлять константную функцию-член, которая модифицирует член: класса. class Screen { public: int ok() const { return cursor; } void error( int ival ) const { cursor = ival; } ... private: string::size type cursor; ... Например, в следующем упрощенном определении: определение функции-члена ok() корректно, так как она не изменяет значения cursor. В определении же error() значение cursor изменяется, поэтому такая функция-член не может быть объявлена константной и компилятор выдает сообщение об ошибке: error: cannot modify a data member within a const member function ошибка: не могу модифицировать данные-члены внутри константной функции-члена Если класс будет интенсивно использоваться, лучше объявить его функции-члены, не модифицирующие данных, константными. Однако наличие спецификатора const в объявлении функции-члена не предотвращает все возможные изменения. Такое объявление гарантирует лишь, что функции-члены не смогут изменять данные-члены, но если класс содержит указатели, то адресуемые ими объекты могут быть модифицированы константной функцией, не вызывая ошибки компиляции. Это часто приводит в недоумение начинающих программистов. Например:
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |