2016-04-05 7 views
1

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

Что такое подходящий идентификатор для этой цели?
Я не обязательно говорю о имени функции, потому что перегруженные функции имеют одно и то же имя, поэтому это не работает.
Правильный ли адрес функции (как используется для делегатов)? Я уверен, что это сработает, но не на 100%. Или может ли функция перемещаться сборщиком мусора, как обычные объекты?
Может быть, другой, лучший способ получить «идентификатор функции»?

Редактировать
Вот пример, чтобы продемонстрировать свое требование (псевдо-код, используемый):

void WorkerFunction (CFuncStep i_oFS) 
{ 
    if (i_oFS.FunctionID == WorkerFunction.FunctionID) 
    { 
    // continue work 
    } 
    else 
    { 
    // start work 
    i_oFS.FunctionID = WorkerFunction.FunctionID; 
    } 

    if (finished_work) 
    i_oFS.FunctionID = null; 
} 

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

+0

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

+0

Ищем оракула - неплохая идея. Тривиально используйте перечисление. –

+0

МетодHandle должен соответствовать вашим требованиям –

ответ

0

@BenVoigt: Спасибо за подсказку MethodHandle!
Это абсолютно то, что мне нужно. Я нашел пример использования на посте SO «Can you use reflection to find the name of the currently executing method?»

Вот мое решение:

using namespace System::Reflection; 

ref class CFuncStep 
{ 
public: 
    int    m_iStep; 
    MethodBase^  m_oMethod; 
    String^   m_sName; 
}; 

void workerfunction (CFuncStep^ i_oFS) 
{ 
    MethodBase^ oMethod = MethodBase::GetCurrentMethod(); 

    if (oMethod != i_oFS->m_oMethod) 
    { 
    i_oFS->m_iStep = 1; 
    i_oFS->m_oMethod = MethodBase::GetCurrentMethod(); 
    i_oFS->m_sName = i_oFS->m_oMethod->Name; 
    } 

    switch (i_oFS->m_iStep) 
    { 
    case 1: 
    case 2: 
    case 3: 
    i_oFS->m_iStep++; 
    break; 

    case 4: 
    i_oFS->m_iStep = 0; 
    i_oFS->m_oMethod = nullptr; 
    i_oFS->m_sName = nullptr; 
    } 
}; 

int main() 
{ 
    CFuncStep^ oFS = gcnew CFuncStep; 
    do 
    { 
    workerfunction (oFS); 
    } 
    while (oFS->m_iStep > 0); 

    return 0; 
} 
Смежные вопросы