И.А. Волкова, А.В. Иванов, Л.Е. Карпов - Основы объектно-ориентированного программирования. Язык программирования С++ (ЧБ) (1114895), страница 5
Текст из файла (страница 5)
При определении метода вне класса с использованием операции ‘::’ прототипы объявления и определения функции должнысовпадать.Метод класса и любую функцию, не связанную ни с каким классом, можноопределить со спецификатором inline:inline int func1();Такие функции называются встроенными.20Спецификатор inline указывает компилятору, что необходимо по возможности генерировать в точке вызова код функции, а не команды вызовафункции, находящейся в отдельном месте кода модуля.
Это позволяет уменьшитьвремя выполнения программы за счет отсутствия команд вызова функции и возврата из функции, которые кроме передачи управления выполняют действия соответственно по сохранению и восстановлению контекста (содержимого основных регистров процессора). При этом размер модуля оказывается увеличенным по сравнению с программой без спецификаторов inline. Следует отметить,что спецификатор inline является рекомендацией компилятору. Данный спецификатор неприменим для функций со сложной логикой. В случае невозможности использования спецификатора для конкретной функции компилятор выдаетпредупреждающее сообщение и обрабатывает функции стандартным способом.По определению методы класса, определенные непосредственно в классе,являются inline-функциям3.7.Указатель thisВ классах С++ неявно введен специальный указатель this – указатель натекущий объект.
Каждый метод класса при обращении к нему получает данныйуказатель в качестве неявного параметра. Через него методы класса могут получить доступ к другим членам класса.Указатель this можно рассматривать как локальную константу, имеющуютип X*, если X – имя описываемого класса. Нет необходимости использовать егоявно. Он используется явно, например, в том случае, когда выходным значениемдля метода является текущий объект.Данный указатель, как и другие указатели, может быть разыменован.При передаче возвращаемого значения метода класса в виде ссылки на текущий объект используется разыменованный указатель this, так как ссылка, какуже было указано, инициализируется непосредственным значением.Пример:class x {. . .public:x& f(.
. .){. . .return *this;}};3.8.Указатель на член классаКроме адресации областей памяти, содержащих информационные объекты,указатели могут содержать адреса членов класса. Технологию создания и использования таких указателей легче описать с использованием конкретногопримера, операторы которого подробно прокомментированы:class X {21int i;public:Х(){i = 1;}int f1(int j){cout << "print i" << i << "\n";return j;}int f2(int j){cout << "reset i \n"; i = 1;return j;}int f3(int j){cout << "set i \n"; i = j;return j;}};typedef int (Х::* pf)(int);int main(){int k, sw, par;x b;pf ff;. .
.switch (sw){case 1: ff=&x::f1;break;case 2: ff=&x::f2;break;case 3: ff=&x::f3;};k = (b.*ff)(par);// см. комментарий 1)// см. комментарий 2)// см. комментарий 3)// см. комментарий 4). . .return 0;}Комментарии:1) ключевое слово typedef вводит новое имя для типа:typedef int (Х::* pf)(int); - pf – тип указателя на методкласса X с одним входным параметром типа int и типом возвращаемогозначения – int.2) pf ff; – создание объекта ff, имеющего введенный тип pf.3) ff = &Х::f1; – указателю ff присваивается адрес одного из методовкласса. Доступ к этому методу по данному указателю через какой-либообъект невозможен (оператор ff = &b.f1; – неверен).
Дело в том, что-указатель на член класса представляется для нестатических членов не22абсолютным, а относительным адресом, то есть смещением относительнобазового адреса класса (указатель на статический член класса представляет собой истинный адрес).4) k =(b.* ff)(par); – разыменование указателя на нестатическийметод класса дает доступ к коду по относительному адресу, которыйприменяется к базовому адресу конкретного объекта (в данном случае –объекта b).Примечание.
В случае объявления методов статическими членами (см. раздел«Статические члены класса») идентификатор pf необходимо объявить обычным указателем на функцию:typedef int (* pf)(int);Разыменование объекта такого типа представляется обычным разыменованием указателя на функцию:k = (*ff)(par);Применение техники разыменования указателя на метод класса являетсяпроявлением динамического полиморфизма, когда исполняемый код для одногои того же оператора (k = (b.*ff)(par)) определяется на этапе исполнения, ане компиляции. В большей мере динамический полиморфизм реализуется виртуальными функциями, описываемыми в следующих разделах.4.Конструкторы и деструкторыКонструкторы и деструкторы являются специальными методами классаКонструкторы вызываются при создании объектов класса и отведении памяти под них.Деструкторы вызываются при уничтожении объектов и освобождении отведенной для них памяти.В большинстве случаев конструкторы и деструкторы вызываются автоматически (неявно) соответственно при описании объекта (в момент отведения памяти под него) и при уничтожении объекта.
Конструктор (как и деструктор) может вызываться и явно, например, при создании объекта в динамической областипамяти с помощью операции new.Так как конструкторы и деструкторы неявно входят в интерфейс объекта, ихследует располагать в открытой области класса.Примечание. Конструкторы и деструкторы могут располагаться и в закрытой области для блокирования возможности неявного создания объекта.
Но в этом случае явноесоздание объекта возможно только при использовании статических методов, являющихся частью класса, а не конкретного объекта. Статические методы описываются далее.Отличия и особенности описания конструктора от обычной функции:1) Имя конструктора совпадает с именем класса2) При описании конструктора не указывается тип возвращаемого значения23Следует отметить, что и обычная процедура может не возвращать значения, атолько перерабатывать имеющиеся данные. В этом случае при описании соответствующей функции указывается специальный тип возвращаемого значенияvoid.В описании конструктора тип возвращаемого значения не указывается непотому, что возвращаемого значения нет. Оно как раз есть. Ведь результатомработы конструктора в соответствии с его названием является созданный объекттого типа, который описывается данным классом.
Страуструп отмечал, что конструктор – это то, что область памяти превращает в объект.Конструкторы можно классифицировать разными способами:1) по наличию параметров:− без параметров,− с параметрами;2) по количеству и типу параметров:−−−−конструктор умолчания,конструктор преобразования,конструктор копирования,конструктор с двумя и более параметрами.Набор и типы параметров зависят от того, на основе каких данных создаетсяобъект.В классе может быть несколько конструкторов. В соответствии с правиламиязыка С++ все они имеют одно имя, совпадающее с именем класса, что являетсяодним из проявлений статического полиморфизма.
Компилятор выбирает тотконструктор, который в зависимости от ситуации, в которой происходит созданиеобъекта, удовлетворяет ей по количеству и типам параметров. Естественным ограничением является то, что в классе не может быть двух конструкторов с одинаковым набором параметров.Деструкторы применяются для корректного уничтожения объектов. Частопроцесс уничтожения объектов включает в себя действия по освобождению выделенной для них по операциям new памяти.Имя деструктора: ~имя_классаУ деструкторов нет параметров и возвращаемого значения.В отличие от конструкторов деструктор в классе может быть только один.Пример: Описание класса.class box{int len, wid, hei;public:box(int l, int w, int h){len = l; wid = w; hei = h;}24}};box(int s){len = wid = hei = s;}box(){len = 2; wid = hei = 1;int volume(){return len * wid * hei;}4.1.Конструктор умолчанияКонструктор без параметров называется конструктором умолчания.Если для создания объекта не требуется каких-либо параметров, то используется конструктор умолчания.
При описании таких объектов после имени классауказывается только идентификатор переменной:class Х{ … };Х x1;Замечание: роль конструктора умолчания может играть конструктор, у которого все параметры имеют априорные значения, например:box (int l = 24, int w = 12, int h = 6);4.2.Конструктор преобразования и конструкторы с двумя и болеепараметрамиЕсли для создания объекта необходимы параметры, то они указываются вкруглых скобках после идентификатора переменной:box b2(1,2,3);box b3(5);Указываемые параметры являются параметрами конструктора класса.
Если уконструктора имеется ровно один входной параметр, который не представляетсобой ссылку на свой собственный класс, то соответствующий конструктор называется конструктором преобразования. Этот конструктор называется так всвязи с тем, что в результате его работы на основе объекта одного типа создаетсяобъект другого типа (типа описываемого класса).Если уже описан класс T и описывается новый класс X, то его конструкторыпреобразования могут иметь любой из следующих прототипов:X(T);X(T&);X(const T&);Последний прототип служит для защиты от изменения передаваемого фактического параметра в теле конструктора, так как при получении ссылки нафактический параметр используется собственно передаваемый объект, а не еголокальная копия.25Примечание.