Функция обратного вызова с C-связью требуется от C ++ - PullRequest
0 голосов
/ 30 сентября 2011

Рассмотрим следующую единственную реализацию C ++, использующую pthread_once для безопасной инициализации потока:

class MySingleton
{
public:
     static MySingleton* Instance();

protected:
     MySingleton() {};
     static void InitOnce();

private:
    static MySingleton* instance;
};


MySingleton* MySingleton::instance = NULL;

pthread_once_t singleton_once_control = PTHREAD_ONCE_INIT;

MySingleton* MySingleton::Instance()
{
     pthread_once(&singleton_once_control, &InitOnce);
     return instance;
}

void MySingleton::InitOnce()
{
     instance = new MySingleton;
}

Проблема в том, что pthread_once нужна функция обратного вызова, чтобы иметь C-linkage.(Хорошо, это всего лишь предупреждение компилятора, и в среде, где я тестирую этот код, работает, потому что соглашения о вызовах функций C и C ++ являются двоично-совместимыми)

Но есть ли хороший образец для реального кроссплатформенного решения?Вы можете создать функцию-обертку C-linkage, но она не может быть частью класса и, следовательно, вызвать частную функцию init InitOnce.

Есть ли какое-либо решение, которое не позволяет сделать InitOnce общедоступным?

PS Да, одиночные игры плохие.Давайте не будем об этом ...

Ответы [ 2 ]

4 голосов
/ 30 сентября 2011

Сделайте InitOnce дружественной функцией вместо этого и дайте ей extern "C" связь.

1 голос
/ 30 сентября 2011

Я не понимаю, почему это должно быть проблемой.Для static функций-членов это только вопрос искажения имени и ничего более.Поскольку весь ваш код на C ++, он всегда будет согласованным.Единственное, что здесь важно, это то, что в C функции без параметров объявляются со списком параметров (void).Я думаю, что это обычно не рекомендуется для C ++ (поскольку в этом нет необходимости), но вы можете попробовать, если это заставит замолчать полученное предупреждение.

...