Использование указателей на функции-члены класса — КиберПедия 

Особенности сооружения опор в сложных условиях: Сооружение ВЛ в районах с суровыми климатическими и тяжелыми геологическими условиями...

История развития пистолетов-пулеметов: Предпосылкой для возникновения пистолетов-пулеметов послужила давняя тенденция тяготения винтовок...

Использование указателей на функции-члены класса

2017-05-23 500
Использование указателей на функции-члены класса 0.00 из 5.00 0 оценок
Заказать работу

Можно определить указатель на функцию-член класса. Синтаксис определения следующий:

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

Например:

void (T::* funcPtr) (int x, int у);

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

Например: this ->* funcPtr (x, y);

или

* this. * funcPtr (x, y);

Указателю на функцию-член класса передается скрытый указатель this (иначе ему нельзя было бы присвоить значение адреса некоторой функции-члена класса).

Следующий пример демонстрирует использование указателей на функцию-член.

class T

{

int a;

public:

T (int A): a (A){}

void MembFunc () { printf ("Hello!");}

void CallMembFunc (void (T::* funcPtr)())

{

this ->*funcPtr();

}

};

int main ()

{

void (T::* funcPtr)()=& T:: MembFunc;

T ob (2000);

ob. CallMembFunc (funcPtr);

}

C++ накладывает определенные ограничения на использование указателей на функции-члены класса:

o указатель на функцию-член класса не может ссылаться на статическую функцию-член класса (так как ей не передается указатель this);

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

 

Массивы объектов класса

Из объектов класса, как и из обычных переменных, можно строить массивы. Синтаксис объявления массива объектов аналогичен синтаксису объявления массивов обычных переменных. Например, следующее объявление создает массив из 10 элементов, которые являются объектами класса AnyClass:

AnyClass obArr [10];

Однако для того, чтобы компилятор смог создать этот массив, он должен использовать конструктор по умолчанию объектов класса. В отношении конструктора по умолчанию действуют перечисленные нами ранее правила. Рекомендуем не полагаться на то, что компилятор сам создаст конструктор по умолчанию, и всегда при объявлении массива объектов некоторого класса включать в этот класс конструктор по умолчанию.

Доступ к элементам массива также аналогичен доступу к массивам переменных любого другого типа. Например:

#include <iostream.h>

class AnyClass

{

int a;

public:

AnyClass (int n){ a = n;}

int GetA (){ return a;}

};

int main ()

{

//Объявление и инициализация массива объектов

AnyClass obArr [5]={13, 17, 21, 23, 27};

int i;

for (i =0; i <5; i ++)

{

//Обращение к элементам массива

cout << obArr [ i ]. GetA ()<<' ';

}

}

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

AnyClass obArr [5] = { AnyClass (13), AnyClass (17), AnyClass (21),

AnyClass (23), AnyClass (27)};

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

В следующем примере создается двумерный массив объектов, конструктор которого содержит два параметра.

# include < iostream.h >

class Coord

{

int x, у;

public:

Coord (int X, int Y){ x = X; у = Y;}

int GetX(){ return x;}

int GetY(){ return y;}

};

int main ()

{

Coord coordArr [4][2] ={ Coord (3,4), Coord (5,6),

Coord (7,8), Coord (9,10),

Coord (ll,12), Coord (13,14),

Coord (15,16), Coord (17,18)};

int i, j;

for (i =0; i <4; i ++)

{

for (j =0; j <2; j ++)

{

cout << coordArr [ i ][ j ]. GetX ()<<' ';

cout << coordArr [ i ][ j ]. GetY ()<<' ';

}

cout << endl;

}

}

Использование указателей для доступа к объектам массива совершенно аналогично их использованию для обычных переменных и структур. Арифметика указателей также аналогична. Инкрементирование указателя приводит к тому, что он указывает на следующий объект массива, декрементирование − к тому, что он указывает на предыдущий объект массива. Рассмотрим пример:

# include < iostream. h >

class Coord

{

int x, у;

public:

Coord (int X, int Y){ x = X; у = Y;}

int GetX (){ return x;}

int GetY (){ return y;}

}

int main ()

{

Coord obArr [4][2]={ Coord (3,4), Coord (5,6),

Coord (7,8), Coord (9,10),

Coord (11,12), Coord (13,14),

Coord (15,16), Coord (17,18)};

int i;

Coord * ptr;

ptr = obArr; //Инициализация указателя адресом массива

for (i =0; i <4; i ++)

{

cout << ptr -> GetX ()<<' ';

cout << ptr -> GetY ()<<"\n";

ptr ++; //Переход на следующий объект

}

}

Эта программа выводит на экран в каждой строке значения переменных х и у текущего элемента массива объектов.

Массивы объектов классов могут располагаться в куче. Например:

# include < iostream. h >

class Coord

{

int x, у;

public:

Coord (int X, int Y){ x = X; у = Y;}

Coord(){ x =0; у =0;}

int GetX () { return x;}

int GetY () { return y;}

};

int main ()

{

int i;

Coord * ptr;

ptr = new Coord [6]; //Создание массива объектов в куче

for (i =0; i <6; i ++)

{

cout << ptr -> GetX ()<<' ';

cout << ptr -> GetY ()<<"\n";

ptr ++; //Переход на следующий объект

}

cout <<"\n";

delete [] ptr; //Удаление массива объектов из кучи

}

Следует обратить внимание, что для удаления массива объектов используется форма оператора delete с квадратными скобками.


Поделиться с друзьями:

Наброски и зарисовки растений, плодов, цветов: Освоить конструктивное построение структуры дерева через зарисовки отдельных деревьев, группы деревьев...

Адаптации растений и животных к жизни в горах: Большое значение для жизни организмов в горах имеют степень расчленения, крутизна и экспозиционные различия склонов...

История создания датчика движения: Первый прибор для обнаружения движения был изобретен немецким физиком Генрихом Герцем...

Типы оградительных сооружений в морском порту: По расположению оградительных сооружений в плане различают волноломы, обе оконечности...



© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!

0.02 с.