QT 中使用 c++ 的指针
之前沒有接觸過 c++,不過聽說 c++ 的指針很坑,直到最近在用 QT / C++ 寫一個 Linux Deepin 系統(tǒng)上檢測網(wǎng)絡(luò)流量和網(wǎng)速的小程序時,發(fā)現(xiàn) c++ 的指針用起來真的特別蛋疼。
不過好在花了幾個小時最終還是明白了指針的用法。
?
有一段代碼的原型大概是這樣的:
QList<NetFlowObject> netflowobj_list;/** 從 list 列表中找出網(wǎng)卡名為 ifname 的 NetFlowObject 對象 **/ bool getNfoFromList(QString ifname, NetFlowObject &nfo);其中 NetFlowObject 是自己寫的一個類,QList 是 Qt 提供的一個鏈表。 getNfoFromList 函數(shù)返回 boolean 型結(jié)果,如果找到相同名稱的網(wǎng)卡,返回 true,并將 nfo 設(shè)為 QList 中找到的 NetFlowObject 對象。否則返回 false。
那么最開始的想法是通過遍歷 QList 找到 NetFlowObject 對象。
bool NetInfo::getNfoFromList(QString ifname,NetFlowObject &nfo) { //-------- A①
foreach(NetFlowObject o, netflowobj_list) { //-------- A②
if(o.getIfName() == ifname) { //-------- A③
nfo = o; return true;
}
}
return false;
}
void NetInfo::someFunction() {// 如果找到相同的 nfo 對象,修改它的數(shù)據(jù) NetFlowObject nfo1;bool finded = getNfoFromList(ifname, nfo1); //-------- B① if(finded) {nfo1.updateRecvBytes(if_recv_bytes.toInt());nfo1.updateTransBytes(if_trans_bytes.toInt());} }嗯,上面的這段代碼很顯然沒有辦法修改 QList 鏈表中的對象的屬性。首先,函數(shù)是傳值的,也就是說 A① 處函數(shù)的參數(shù) nfo 是不會影響 someFunction 里 B① 處的 nfo1 對象的。nfo1 對象的屬性改變同樣也不會影響 nfo 對象。
通過函數(shù)的參數(shù)傳遞的只是 nfo1 對象的一個副本,兩個對象之間不會影響。
其次,A②處的 foreach 這個便捷的循環(huán)也是提供 QList 對象的一個副本,這樣的話,更加沒有辦法修改找到的 NetFlowObject 對象了。
好吧,這個錯誤是 c++ 最常見也是最愚蠢的錯誤,那么想要得到 QList 中的某個 NetFlowObject 對象的引用,函數(shù)傳遞的就不能是 NetFlowObject 對象了,那么就改成 NetFlowObject * 也就是指針吧。另外,將循環(huán)改為 for 計數(shù)循環(huán)。
代碼如下
bool NetInfo::getNfoFromList(QString ifname,NetFlowObject *nfo) {for(int i = 0; i < netflowobj_list.count(); i++) {NetFlowObject o = netflowobj_list[i];// PrintUtil::print(o.getIfName() + " === " + QString::number(o.getLatestRecvBytes()));if(o.getIfName() == ifname) {*nfo = netflowobj_list[i]; // 將指針?biāo)赶虻?NetFlowObject 對象修改為 o -------C①return true;}}return false; }相應(yīng)的,
bool finded = getNfoFromList(ifname, &nfo1);但是這樣做,發(fā)現(xiàn)修改 nfo1 對象仍然沒有效果, QList 中 NetFlowObject 對象的屬性依然沒有改變。恩沒有錯,上面代碼 C① 處又是傳遞的副本。
這里要說一下 QList 對象的 at(i) 函數(shù)和 QList[i] 數(shù)組形式得到的對象是不同的。函數(shù)原型為 const T &QList.at(int i) const,也就是不能通過 at() 的返回值對 nfo 對象進行修改,
而數(shù)組形式的函數(shù)原型是 T &QList::operator[] (int i),也就是用起來和平常的數(shù)組沒什么太大區(qū)別。
?
既然一層引用不能達(dá)到效果,那么,函數(shù)傳遞的時候,就傳一個 NetFlowObject * 對象的指針,也就是作為 NetFlowObject 對象的指針的引用。(這個指針的指針說起來太繞口了,第二個指針改稱引用,不然腦子就漿糊了),貼出最終的代碼:
bool NetInfo::getNfoFromList(QString ifname,NetFlowObject **nfo) {for(int i = 0; i < netflowobj_list.count(); i++) {NetFlowObject o = netflowobj_list[i]; // PrintUtil::print(o.getIfName() + " === " + QString::number(o.getLatestRecvBytes()));if(o.getIfName() == ifname) {*nfo = &netflowobj_list[i]; // 將指針?biāo)赶虻?NetFlowObject 指針修改為 QList 中第 i 個對象的引用return true;}}return false; }void NetInfo::someFunction() {NetFlowObject *nfo;bool finded = getNfoFromList(ifname, &nfo);if(finded) {nfo->updateRecvBytes(if_recv_bytes.toInt());nfo->updateTransBytes(if_trans_bytes.toInt());} }通過兩層引用,最終達(dá)到了修改 QList 鏈表中對象的目的。
感覺還有一種解決方法,就是將函數(shù)原型?getNfoFromList 修改成 NetFlowObject * getNfroFromList(QString ifname);
找到相應(yīng)的對象后直接返回該對象的引用,這樣就不用通過函數(shù)參數(shù)傳遞兩層引用了。
?
-------------------------- ?思考 -------------------------
引用指針繞的頭都暈了,而且這個錯誤理論上應(yīng)該屬于邏輯錯誤(編譯時不會報錯,運行時不會發(fā)生異常),但是特喵的就是結(jié)果不對,debug 起來也很蛋疼,通過長時間的分析和總結(jié)才能得到正確的結(jié)果。
?
轉(zhuǎn)載于:https://www.cnblogs.com/brifuture/p/6037485.html
總結(jié)
以上是生活随笔為你收集整理的QT 中使用 c++ 的指针的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android游戏开发笔记(一)
- 下一篇: VC学习笔记---ATL MFC CLR