这是我的第一个问题,这是一个无趣的问题:)。
我遇到了C ++和Qt 4.6的问题,因为我想通过QMetaMethod :: invoke()方法分解我调用QObject的一些公共插槽的一些代码。
我面临的问题是,Q_ARG宏定义如下:
#define Q_ARG(type, data) QArgument<type >(#type, data)
那说我应该在编译时知道类型。但另一方面,我得到了这个方法的论据,它们将作为QVariants出现。我可以通过 - &gt; 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而不是设置“supported”标志,但这会强制我在这种情况下进行堆分配,因为“param.value()”调用返回QVariant值的副本,我应该通过new或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] [...]);
这并不让我高兴,因为它不是类型安全的。所以我问自己的问题是如何解决这个宏,并用一个可以进行堆栈分配而不是堆分配的方法替换它?
我事先感谢你们的帮助和兴趣。
答案 0 :(得分:4)
这是我的问题,我不想要 在这个方法中做堆分配, 因为这会被称为千人 时间(这是一个请求处理 模块)。
不要再猜测表演问题。是的,堆栈分配更快,是的,应该避免在不需要时复制。但是,这对我来说似乎是过早优化。
您似乎正在构建一个非常复杂的代码体系结构,以节省一些CPU周期。最后,您将无法可靠地分辨出被调用的内容和次数。你将拥有一个难以维护的代码。
我的建议是:专注于代码的正确性和简单性,如果您真的在某些时候遇到性能问题,配置文件您的代码,看看有什么问题。