在C++中,QString
和 QString&
有本質區別,尤其是在參數傳遞和內存管理方面:
1. QString
(按值傳遞)
- 創建副本:傳遞時會創建完整的字符串副本
- 內存開銷:可能涉及深拷貝(特別是大字符串時)
- 修改不影響原對象:函數內修改不影響調用方的原始字符串
- 使用場景:需要獨立操作字符串副本時
void modifyString(QString str) { // 按值傳遞str.append(" World"); // 修改副本
}// 調用
QString original = "Hello";
modifyString(original);
qDebug() << original; // 輸出: "Hello" (未改變)
2. QString&
(引用傳遞)
- 無拷貝操作:直接操作原始字符串
- 零內存開銷:傳遞的是原始對象的"別名"
- 修改影響原對象:函數內修改直接影響調用方的原始字符串
- 使用場景:需要修改原始字符串或避免拷貝開銷時
void modifyStringRef(QString& str) { // 引用傳遞str.append(" World"); // 修改原始對象
}// 調用
QString original = "Hello";
modifyStringRef(original);
qDebug() << original; // 輸出: "Hello World" (已改變)
最佳實踐:const QString&
對于只讀操作,推薦使用 常量引用,兼具效率和安全性:
// 高效讀取字符串(無拷貝,禁止修改)
void printString(const QString& str) {qDebug() << "Content:" << str;// str.append("!"); // 編譯錯誤!const保護
}
對比總結
特性 | QString | QString& | const QString& |
---|---|---|---|
是否創建副本 | ? | ? | ? |
能否修改原對象 | ? | ? | ? (const保護) |
內存開銷 | 可能較高 | 零開銷 | 零開銷 |
典型使用場景 | 需要獨立副本時 | 需要修改原對象時 | 只讀訪問時 |
傳遞大字符串的效率 | 低(深拷貝) | 高 | 高 |
關鍵注意事項
- Qt的隱式共享:即使按值傳遞,Qt字符串在未修改時可能共享數據(寫時復制)
- 返回引用:永遠不要返回局部變量的引用!
// 危險!返回已被銷毀的局部變量 QString& badExample() {QString local = "test";return local; // 會導致未定義行為 }
- C++11移動語義:對于臨時字符串,使用
QString&&
可啟用移動構造void efficientMove(QString&& str) {QString local = std::move(str); // 移動而非拷貝 }
建議:80%的情況下使用const QString&
,需要修改時用QString&
,明確需要副本時才用QString
。