Войти
ПрограммированиеFAQОбщее

Указатели на функции-члены классов

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

#include <iostream>

using namespace std;

class Test
{
public:
     void foo()
     {
          cout << "Test::foo called" << endl;
     }
};

int main()
{
     //объявляем тип указателя:
     typedef void (Test::* pToFunc)();

     //создаём объект этого типа и инициализируем его:
     pToFunc pt = &Test::foo;

     //создаем объект класса Test
     Test test;

     //с помощью объекта вызываем функцию-член, адрес который хранится в pt
     //обратите внимание на *
     (test.*pt)();

     // Можно и по указателю:
     Test *test2 = new Test; 

     (test2->*pt)();

     delete test2;
}

Есть в с++ одна интересная особенность: в этом языке не существует типа для результата
работы функций (test.*pt). К нему можно только применить оператор вызова функции.

В стандарте языка C++ сказано: "Если результатом выполнения операторов .* и ->* является функция, этот результат может быть использован лишь в качестве операнда оператора вызова функции ()".

21 декабря 2005 (Обновление: 25 янв. 2006)

Комментарии [248]

Страницы: 1 2 316 17 Следующая »
#1
15:56, 19 фев. 2013

Не понимаю, а зачем??? Я здесь увидел лишь альтернативный способ вызвать функцию, причем, способ нечитабельный) Может я что-то упустил из вида?

#2
16:29, 19 фев. 2013

Иногда удобней пользоваться массивом из указателей на разные функции, чем катать простыни из switch или if.. else if

#3
16:32, 19 фев. 2013

Я такую штуку применял:
1. чтобы избавится от толстого switch.
2. при динамической подмене функции в зависимости от железа.

#4
17:26, 19 фев. 2013

ITcrusader
>Не понимаю, а зачем??? Я здесь увидел лишь альтернативный способ вызвать функцию, причем, способ нечитабельный) Может я что-то упустил из вида?
Я для консольных команд так делал.
В консольную команду можно биндить практически любой метод класса. Не затачивая его специально для этого. Так что это очень полезная штука.

#5
18:06, 19 фев. 2013

Указатель на метод класса? Извращение же.
Если тебе нужен указатель на метод класса - ты пишешь неправильный код.

#6
18:11, 19 фев. 2013

> Указатель на метод класса? Извращение же.
Возможно, ща начнется ....
> Если тебе нужен указатель на метод класса - ты пишешь неправильный код.
Это всего лишь один из инструментов при написании программы. Причем хороший инструмент.
Хороший прог видит такие вещи сразу.

#7
18:12, 19 фев. 2013

asvp
> Причем хороший инструмент.
Это как раз плохой инструмент - он усложняет флоу и понимаемость программы

#8
18:27, 19 фев. 2013

Вполне нормальная практика. Пользуюсь и довольно часто. У себя обвернуты указатели в шаблоны и фабричную функцию создания, дабы облегчить вызовы. Есть хорошая статья на эту тему: http://www.rsdn.ru/article/cpp/delegates.xml

#9
18:46, 19 фев. 2013

Юзаю у себя в своём GUI для вызова какого-либо фанка при нажатии кнопки. Очень полезная вещь.

#10
18:57, 19 фев. 2013

Неплохо было бы написать об подводных камнях этих указателей. Например, разный размер в зависимости от видов наследования. Или то, что приведение указателя на метод производного класса к указателю на базовый может быть сделано только через reinterpret_cast, что UB.

#11
19:03, 19 фев. 2013

В C++ это ужасно нечитабильно, особенно если биндимая функция с параметрами. Лучше, при возможности, бустом биндить.

#12
19:09, 19 фев. 2013

Smrdis
лучше по возможности не использовать буст, потому, что буст:
> это ужасно нечитабильно
:D

#13
19:20, 19 фев. 2013

StiX
> лучше по возможности не использовать буст, потому, что буст:
А std::tr1::bind, пойдет?

#14
10:40, 20 фев. 2013

asvp
> Хороший прог видит такие вещи сразу.

Ну, допустим я никудышный прог. Но за 6 лет использования C++ ни разу не довелось использовать данную возможность, о предоставлении которой языком я знал.
Мне не хотелось бы разводить холивар (если бы хотел, создал бы тему типа "C++ - не более чем извращенный способ прострелить себе ногу" или "apple рулит, Android - говно)" или "открывающая скобка в определениях функций должна быть в одной строке с заголовком функции" :) )
На тему целесообразности использования указателей на функции члены класса ответ я ищу, в том числе, самостоятельно. НО пока не нашел достойного примера применения. Если таков имеется, с удовольствием бы глянул:)

Страницы: 1 2 316 17 Следующая »
ПрограммированиеFAQОбщее

Тема в архиве.