Классы и массивы. Массивы указателей на методы-члены класса. Примеры

Классы и массивы. Массивы указателей на методы-члены класса. Примеры


Содержание



1. Объявление массива указателей на методы, которые есть членами класса с использованием средства typedef. Общая форма

В C++ можно объявлять указатель на метод некоторого класса. Итак, можно объявлять массив указателей на методы некоторого класса. Понятно, что сигнатура методов может быть одинаковой.
Чтобы объявить массив указателей на методы класса 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;
  • глобальный объект класса с именем obj;
  • тип данных 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? Общая форма

Массив указателей на методы класса можно объявить без использования средства 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;


Связанные темы