Это мой первый вопрос, и это нубистский вопрос:).
Я сталкиваюсь с проблемой с C ++ и Qt 4.6, потому что я хочу разложить часть своего кода, которая вызывает какой-то общедоступныйслоты QObject с помощью метода QMetaMethod :: invoke ().
Проблема, с которой я сталкиваюсь, заключается в том, что макрос Q_ARG определяется следующим образом:
#define Q_ARG(type, data) QArgument<type >(#type, data)
То естьчто я должен знать во время компиляции тип.Но с другой стороны, я получаю свои аргументы для метода, которые приходят как QVariants.Я могу получить их типы через метод доступа -> type (), который возвращает значение перечисления типа QVariant :: Type, но, естественно, не как тип времени компиляции.
Таким образом, чтобы просто генерировать аргументы для вызова,Я сделал следующий макрос:
#define PASS_SUPPORTED_TYPE(parameterToFill, requiredType, param, supported) { \
\
switch (requiredType) { \
case QVariant::String: \
parameterToFill = Q_ARG(QString, \
param.value<QString>()); \
break; \
\
case QVariant::Int: \
parameterToFill = Q_ARG(int, param.value<int>()); \
break; \
\
case QVariant::Double: \
parameterToFill = Q_ARG(double, param.value<double>()); \
break; \
\
case QVariant::Char: \
parameterToFill = Q_ARG(char, param.value<char>()); \
break; \
\
case QVariant::Bool: \
parameterToFill = Q_ARG(bool, param.value<bool>()); \
break; \
\
case QVariant::Url: \
parameterToFill = Q_ARG(QUrl, param.value<QUrl>()); \
break; \
\
default: \
supported = false; \
\
} \
\
supported = true; \
}
То же самое можно было бы сделать в методе, который мог бы возвратить true или false вместо установки флага «поддерживаемого», но это заставило бы меня сделать выделение кучи в этом случаепотому что вызов "param.value ()" возвращает копию значения QVariant, которое я должен хранить в куче через новый или через memset.
И это моя проблема, я не хочуделать выделение кучи в этом методе, потому что он будет вызываться тысячи раз (это модуль обработки запросов).
for (int k = 0; k < methodParams.size(); ++k) {
QVariant::Type paramType = QVariant::nameToType(methodParams[k].toAscii());
[...]
bool supportedType = false;
PASS_SUPPORTED_TYPE(
paramsToPass[k],
paramType,
params[k],
supportedType);
[...]
}
metaMethod.invoke(objectToCall, paramsToPass[0], paramsToPass[1], paramsToPass[2] [...]);
Это меня не радует, потому что это небезопасно.Поэтому я задаю себе вопрос: как я могу запустить этот макрос и заменить его на метод, который будет выполнять выделение стека, а не выделение кучи?
Заранее благодарю всех за помощь и интерес.