Статический массив указателей на методы

Я столкнулся с ошибкой, которую я не понимаю.

Я пытаюсь создать и использовать статический массив указателей на методы. Объявление в моем классе выглядит так:

static void (Client::*packetHandler[Op::handledOpcodeMax - Op::handledOpcodeMin + 1])(QByteArray &data);

Инициализация в моих файлах .cpp происходит так:

void (Client::*packetHandler[Op::handledOpcodeMax - Op::handledOpcodeMin + 1])(QByteArray &data);

Вот и возникают проблемы, в одном из методов класса моего клиента я пытаюсь использовать массив указателей этого метода. Я пробовал несколько способов, например:

(this->*packetHandler[_opcode])(data);

Я сказал, что не понимаю проблемы, позвольте мне объяснить, почему. Запуск make в моем коде приводит к правильной компиляции, но возникла проблема при компоновке.

client.cpp:71: undefined reference to `Client::packetHandler'

Это сообщение повторяется 5 раз.

Любая помощь приветствуется. Спасибо.


person Xaqq    schedule 22.09.2011    source источник
comment
statics являются локальными для вашей единицы перевода. возможно, экспорт был бы в порядке.   -  person Captain Giraffe    schedule 22.09.2011
comment
Было бы слишком неприятно говорить вам использовать boost:: function вместо этого?   -  person George Godik    schedule 22.09.2011
comment
Я настоятельно рекомендую несколько typedefs, чтобы убрать этот беспорядок.   -  person Kerrek SB    schedule 22.09.2011
comment
есть ли шанс, что в заголовочном файле существует несколько строк?   -  person stdcall    schedule 23.09.2011
comment
@KerrekSB typedefs сделали бы их чище, но не так забавно.   -  person rodrigo    schedule 23.09.2011
comment
@CaptainGiraffe Я действительно не понимаю, ключевое слово static находится только в моем заголовочном файле. static void (Client::*packetHandler[Op::handledOpcodeMax - Op::handledOpcodeMin + 1])(QByteArray &data); находится в моем заголовочном файле. @George Джордж Ну да, потому что я хочу сделать это самостоятельно (в целях обучения): P. @Kerrek Может быть, позже мне нужно четко понять, что происходит: D. @Mellowcandle Ну, первая строка принадлежит client.hpp   -  person Xaqq    schedule 23.09.2011
comment
try (this-›packetHandler[_opcode])(data); вместо того, чтобы идти косвенно через запись таблицы (т. е. не (this->*packetHandler[_opcode])(data);)   -  person Pete Wilson    schedule 23.09.2011
comment
можете ли вы опубликовать полную командную строку, используемую при компиляции и компоновке? Я имею в виду полностью построить журнал. Другой совет - создать локальную переменную соответствующего типа func-ptr, скажем, myvar и инициализировать с правильным ptr, а затем изменить (this->*packetHandler[_opcode])(data); на myvar(data);, а затем посмотреть, где ошибка.   -  person Kashyap    schedule 23.09.2011
comment
@thekashyap Я пытался сделать это: void (Client::*ptr)(QByteArray &); ptr = packetHandler[_opcode]; Это дает мне undefined reference to Client::packetHandler'. Я предполагаю, что проблема связана с инициализацией массива, я имею в виду, кажется, что void (Client::*packetHandler[Op::handledOpcodeMax - Op::handledOpcodeMin + 1])(QByteArray &data); не делает массив статическим членом клиентского класса. Или что-то вроде этого.   -  person Xaqq    schedule 23.09.2011


Ответы (2)


void (Client::*packetHandler[Op::handledOpcodeMax - Op::handledOpcodeMin + 1])(QByteArray &data); объявляет глобальную переменную с именем packetHandler. Вы хотите определить свою переменную класса, которая нуждается в дополнительном Client::, например:

void (Client::*Client::packetHandler[Op::handledOpcodeMax - Op::handledOpcodeMin + 1])(QByteArray &data);
person Neil    schedule 22.09.2011
comment
Ха-ха, спасибо, Нил. Я думал о чем-то подобном после комментария @thekashyap. Я пробовал void (Client::Client::*packetHandler[Op::handledOpcodeMax - Op::handledOpcodeMin + 1])(QByteArray &data);. Не повезло с * позицией :D. Спасибо :) - person Xaqq; 23.09.2011
comment
Просто показывает, насколько важен комментарий Керрека С.Б. о определении типов.. :) - person Kashyap; 23.09.2011

Client::*packetHandler — это указатель на функцию-член, указывающий на функцию-член с именем Client::packetHandler. Я не уверен, как сделать указатель функции-члена, указывающий на произвольную функцию-член, которую вы, похоже, хотите сделать. Я думаю, что Джордж прав. Вам следует подумать об использовании чего-то вроде boost::function или std::tr1::function или написать свой собственный класс-оболочку функции-члена.

person Sean    schedule 22.09.2011
comment
Чтобы сделать указатель функции, указывающий на любую функцию-член, которую вы хотите, просто, вам не нужно делать ничего особенного. Моя проблема в том, что я хочу, чтобы этот массив был статическим элементом моего класса. Удаление ключевого слова static в заголовочном файле делает компиляцию и связывание работающими. - person Xaqq; 23.09.2011