Класи і масиви. Масиви покажчиків на методи, що є членами класу. Приклади

Класи і масиви. Масиви покажчиків на методи, що є членами класу. Приклади


Зміст


1. Оголошення масиву покажчиків на методи, що є членами класу з використанням засобу typedef. Загальна форма

Дозволяється оголошувати покажчик на метод деякого класу. Отже, можна оголошувати масив покажчиків на методи деякого класу. Зрозуміло, що сигнатура методів має бути однаковою.
Щоб оголосити масив покажчиків на методи класу A потрібно оголосити тип, що є покажчиком на метод класу A. Для цього потрібно використати засіб typedef за зразком, як показано нижче

typedef type (A:: * PType)(arguments_list);

де

  • type – тип, що повертають методи класу;
  • argument_list – список аргументів методів класу (має бути однаковий для усіх методів);
  • A – назва класу, в якому оголошуються методи, які потрібно об’єднати в масив;
  • PType – назва нового типу, який визначає покажчик на метод з класу A.

Якщо визначено тип PType, то масив покажчиків можна оголосити за такою формою

PType ArrayName[size];

де

  • PType – наперед визначений тип, що є покажчиком на метод класу A;
  • ArrayName – ім’я масиву покажчиків на методи класу A;
  • size – кількість елементів у масиві покажчиків ArrayName.

Щоб встановити значення масиву в деякий метод класу A, можна використати таку загальну форму

ArrayName[index] = &A::SomeMethod;

де

  • ArrayName – ім’я масиву покажчиків;
  • index – позиція (індекс) в масиві покажчиків;
  • A – клас, на методи якого вказує масив покажчиків;
  • SomeMethod – деякий метод класу A.

2. Приклад оголошення та використання масиву покажчиків на методи, що є членами класу

Нижче наведено приклад в якому демонструється використання масиву покажчиків на методи класу. У прикладі оголошується:

  • клас з іменем X
  • глобальний об’єкт класу з іменем objX;
  • тип даних FP, що описує покажчик на метод класу X;
  • масив покажчиків A, який ініціалізується адресами методів класу X;
  • глобальна функція SetMember().

У класі оголошуються:

  • внутрішні змінні класу value, total, count;
  • конструктор класу за замовчуванням;
  • методи доступу SetV(), SetT(), SetC(). Значеннями адрес (точок входу) цих методів буде ініціалізуватись глобальний масив покажчиків A;
  • методи читання внутрішніх змінних класу GetV(), GetT(), GetC().


Лістинг класу з функцією _tmain() для додатку типу Win32 Console Application має вигляд:

#include "stdafx.h"
#include <iostream>
using namespace std;

// оголошення класу X
class X
{
    int value;
    int total;
    int count;

    public:
    X() { value = total = count = 0; }
    void SetV(int nv) { value = nv; }
    void SetT(int nt) { total = nt; }
    void SetC(int nc) { count = nc; }
    int GetV(void) { return value; }
    int GetT(void) { return total; }
    int GetC(void) { return count; }
};

X objX;

typedef void (X::*FP)(int); // новий тип даних FP
FP A[] =
{
    &X::SetV, // A[0] <=> &X::SetV
    &X::SetT,
    &X::SetC,
    NULL
};

// функція, що встановлює покажчик
void SetMember(void (X::*fPtr)(int), int t)
{
    (objX.*fPtr)(t); // виклик методу з об'єкту за покажчиком fPtr
}

// точка входу в програму
int _tmain(int argc, _TCHAR* argv[])
{
    // масиви покажчиків на функції-члени класу
    SetMember(&X::SetV, 8); // objX.value = 8
    int t;
    t = objX.GetV(); // t = 8

    SetMember(A[0], 10);
    t = objX.GetV(); // t = 10

    SetMember(A[1], 15);
    t = objX.GetT(); // t = 15

    // демонстрація простого покажчика на функцію
    void (X::*pF)(int);
    pF = &X::SetC; // pF вказує на метод SetC деякого класу

    SetMember(pF, 13); // виклик SetMember, в якій перетворюється покажчик
    t = objX.GetC(); // t = 13

    // встановлення останнього елементу масиву A на метод X::SetT
    A[3] = &X::SetT; // просто демонстрація використання покажчика на метод класу

    return 0;
}

3. Яким чином оголосити масив покажчиків на методи класу без використання засобу typedef? Загальна форма

Можна одразу оголосити масив покажчиків на методи деякого класу. Загальна форма такого оголошення:

type (A:: * ArrayName[size])(arguments_list);

де

  • type – тип, що повертають методи класу на які оголошується масив покажчиків;
  • ArrayName – ім’я масиву покажчиків;
  • size – розмір масиву ArrayName;
  • arguments_list – список аргументів, що отримують методи класу, на які оголошується масив покажчиків.

Наприклад. На методи класу X, описаного в п.2, можна оголосити масив B з покажчиків наступним чином:

// масив покажчиків на методи класу X без використання typedef
void (X::*B[5])(int);

Якщо потрібно ініціалізувати масив B, то можна написати так:

// масив покажчиків на методи класу X без використання typedef
void (X::*B[5])(int) = 
{
    &X::SetC,
    &X::SetV,
    NULL,
    NULL,
    NULL
};

Присвоєння значень елементам масиву B може виглядати так:

// присвоєння значень
B[2] = &X::SetV;
B[3] = &X::SetC;
B[4] = &X::SetT;


Зв’язані теми