Неконвертируемый конструктор

Неконвертируемый конструктор создается при помощи спецификатора функций explicit, который применяется только к конструкторам. Обычно, если имеется конструктор, принимающий только один аргумент, то для инициализации объекта ob можно использовать варианты: ob(x), либо ob = x (т.к. при создании такого конструктора мы неявно указываем преобразование из типа аргумента в тип данного класса). Если же конструктор определен с помощью explicit, то он будет задействован только в случае, когда для инициализации используется обычный синтаксис конструктора, т.е. ob(x). При этом автоматических преобразований выполняться не будет, и вариант ob = x не будет разрешен.


 


Деструкторы

Деструктор - особый вид метода, применяемого для освобождения памяти, занимаемой объектом. Имя деструктора совпадает с именем класса, но перед ним ставится символ «~» (тильда). Деструктор определяет операции, которые необходимо выполнить при уничтожении объекта. Деструктор вызывается автоматически, когда объект выходит из области видимости для локальных объектов - при выходе из блока, в котором они были объявлены; для глобальных – как часть процедуры выхода из main. Для объектов, заданных через указатели, деструктор выполняется неявно при использовании операции delete.

Деструктор:

· не имеет аргументов и возвращающего значения

· не может быть объявлен как const или static (но может быть virtual)

· не наследуется

В иерархии классов деструкторы, в отличие от конструкторов (которые выполняются в порядке своего "классового происхождения"), выполняются в обратном порядке.

Если деструктор не определен явным образом, то компилятор создает автоматически пустой деструктор. Явным образом деструктор требуется описывать в случае, когда объект создает указатели на память, выделяемую динамически. Иначе при уничтожении объекта память, на которую ссылались его указатели, не будет помечена как свободная. Указатель на деструктор определить нельзя.

Деструктор можно вызывать явным образом путем указания полностью уточненного имени.

Деструкторы, вызываемые неявно. Если программа завершается с использованием exit, то вызывается деструктор только глобальных объектов. При завершении программы, в которой использовались объекты некоторого класса функции abort, деструктор не вызывается.

Пример 1

class String {

public:

// набор конструкторов

String();

String(const char*);

String(const String&);

// деструктор

~String();

 private:

...

 }


Указатели на элементы класса

К элементам класса можно обращаться с помощью указателей. Для этого определены следующие операции:.* и –>. Указатели на поля и методы класса определены по-разному.

Формат указателя на метод класса: <возвращаемый_тип> (<имя_класса>::*<имя_указателя>)(<параметр>)

Пример 1

int get_health() {return health;}

int get_ammo() {return ammo;}

int (monstr::*pget)();

Если указатель задавать в качестве параметра функции, это дает возможность передавать в функцию имя метода.

Пример 2

void fun(int (monstr::*pget)())

{

(*this.*pget)(); /* */

(this -> pget)(); /* */

}

Можно создать указатель на конкретный метод с помощью операции взятия адреса:

Пример 3

/* присваивание значения указателю*/

pget = &monstr::get_health;

monstr Vasia.*p;

p = new monstr;

/* вызов функции через операцию.* */

int Vasia_health=(Vasia.*pget)();

/* вызов функции через операцию ->* */

int p_health=(p->*pget)();


 


Правила использования указателей на методы класса

· Указателю на метод можно присваивать только адреса методов, имеющих соответствующий заголовок.

· Нельзя определить указатель на статический метод класса.

· Нельзя преобразовать указатель на метод в указатель на обычную функцию, не являющуюся элементом класса.

Как и указатели на обычные функции, указатели на методы класса используются в том случае, когда возникает необходимость вызывать метод, имя которого неизвестно. Однако существуют различия между указателем на метод и на функцию (имя переменной). Указатель на метод не ссылается на определенный адрес памяти. Указатель на метод имеет сходство с индексом в массиве, так как задает смещение. Конкретный адрес в памяти получается путем сочетания указателя на метод класса с указателем на определенный объект.

Формат указателя на поле класса: <тип_данных>(<имя_класса>::*<имя_указателя>);

В определение указателя можно включить его инициализацию в такой форме: &имя_класса::имя_поля; При это поле должно быть в области public.


 


Неявный параметр this

Когда компонентная функция вызывается для конкретного объекта, то этой функции автоматически и неявно передается в качестве параметра указатель на тот объект, для которого она вызывалась. Этот указатель имеет специальное имя и определен как константный в каждой функции класса.

<имя класса>*const this = <адрес объекта>

В соответствии с описанием этот указатель менять нельзя, однако в каждой принадлежащей классу функции он указывает на тот объект, для которого данная функция вызывается. То есть указатель this является дополнительным (скрытым) параметром каждой нестатической компонентной функции. Этот параметр используется для доступа к полям конкретного объекта. Для иллюстрации использования указателя this добавим в приведенный класс monstr новый метод, возвращающий ссылку на более здорового из двух монстров, один из которых вызывает метод, а другой передается ему в качестве параметра. Метод необходимо поместить в секцию public

Пример 1

monstr &the_best(monstr &M)

{

if(health > M.get_health())

return *this;

return M;

}

monstr Vasia(50), Super(200);

/* Новый объект Best инициализируется значениями полей Super */


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: