Указатели на функции-члены — только адрес?

#c #function-pointers #functor #member-function-pointers #pointer-to-member

#c #указатели на функции #функтор #указатель на элемент

Вопрос:

http://www.codeproject.com/KB/cpp/fastdelegate2.aspx

Во втором абзаце введения в приведенной выше статье говорится: «Это связано с дорогостоящим выделением памяти кучи, которое требуется для хранения функции-члена и связанного объекта, для которого выполняется вызов функции-члена «. .. Я этого не понимаю? Действительно ли нужно копировать и сохранять объект и функцию-член? Разве он не хранит только адрес функции-члена?

Комментарии:

1. Нестатическая функция-член связана с определенным объектом. Что-то вроде matrix->Invert() инвертирует одну конкретную матрицу, поэтому она должна знать, с какой матрицей работать.

Ответ №1:

Повышение.Функция является более общей и мощной, чем необработанные указатели на функции: они могут хранить все, что можно вызвать с определенной сигнатурой. Однако с такой гибкостью связаны затраты на хранение и время выполнения.

Раздел Разных заметок Boost.В документации по функциям немного больше говорится об этом, но для подведения итогов:

  • Повышение.Функциональный объект хранит указатель на функцию-член и два указателя на данные внутри.
  • Может потребоваться выделение кучи при хранении функтора, размер которого превышает определенный размер.
  • Вызываю Boost.Объект функции приводит либо к одному, либо к двум вызовам через указатель на функцию, в зависимости от того, что именно было сохранено.

Сказав все это, я использовал Boost.Функционирует широко, и никогда не было ситуации, когда его затраты на хранение или время выполнения действительно проявлялись при профилировании, поэтому важно ли что-либо из этого или нет, будет зависеть от вашего фактического использования.

Ответ №2:

Нет, вы не можете вызвать функцию-член, используя только указатель на метод. Причина в том, что методы вызываются в контексте ( this ), объекте, для которого вызывается метод. Если у вас есть только указатель на функцию-член, вы не можете знать, к какому объекту следует применить метод. Однако, если функция-член является static , то у нее НЕТ контекста, потому что статические функции-члены могут вызываться без создания экземпляра объекта.

Итак, для вызова функции-члена вам нужен указатель на функцию, ПЛЮС некоторая ссылка на объект, определяющий контекст, в котором будет выполняться вызов функции-члена.

Отвечает ли это на ваш вопрос?

Комментарии:

1. Вроде как да, но разве ссылка не будет в значительной степени указателем на объект? Итак, это два указателя? Это все, что есть? Из строки, которую я процитировал, звучит так, как будто это еще не все?

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

3. хм .. Значит, иногда это будет «дорогостоящее выделение кучи», которое они имеют в виду в этой цитате? Потому что выделение памяти для двух указателей не было бы дорогостоящим.. Я использовал std / boost :: function много раз, поэтому я знаю, как это делается..

4. boost::function действительно выделит кучу для хранения копии контекста (либо копии всего объекта, либо копии ссылки, если вы используете boost::ref ). Является ли это дорогим или нет, относительно. Как вы говорите, выделение нескольких указателей не имеет большого значения, но это все равно выделение, поэтому, если вы делаете это в цикле, вы будете вызывать сложный системный вызов много раз…