2010-09-02 61 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

相關問題