2010-09-02 92 views
2

这是我的第一个问题,这是一个noobish问题:)。避免堆分配的宏?在这种情况下,这是不好的?

我面临着C++和Qt 4.6的问题,因为我想通过QMetaMethod :: invoke()方法来分解一些调用QObject公共槽的代码。

我现在面临的问题是,在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] [...]); 

这不要我,因为它不是类型安全的。所以我问自己的问题是我怎么才能发现这个宏,并用一个可以进行堆栈分配而不是堆分配的方法取代它?

我提前感谢大家的帮助和关心。

+1

哎唷!这是一个宏观的地狱。难怪为什么你想摆脱它。 – ereOn 2010-09-02 12:24:46

+2

我可以获得2010年代码气味奖。 :) – daminetreg 2010-09-02 12:28:31

回答

4

这是我的问题,我不想 做堆分配在这种方法中, 因为这将让调用数千时间 (这是处理 模块的请求)。

不要再猜测演出的问题。是的,堆叠分配速度更快,是的,当不需要时应避免复制。但是,这看起来像不成熟的优化给我。

看来你正在构建一个非常复杂的代码架构,以节省几个CPU周期。最后,你将无法可靠地说出被调用的内容和次数。你会有一个不可维护的代码。

我的建议是:专注于代码的正确性和简单性,如果您真的在某些时候面临性能问题,请使用配置文件查看错误代码。

+0

谢谢,我会用堆分配来完成它,我总是可以稍后再回来优化一些部分。 – daminetreg 2010-09-02 12:37:10

+1

+1好建议。过早优化是一种代码异味。 – 2010-09-02 13:07:59