#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
). Является ли это дорогим или нет, относительно. Как вы говорите, выделение нескольких указателей не имеет большого значения, но это все равно выделение, поэтому, если вы делаете это в цикле, вы будете вызывать сложный системный вызов много раз…