Qt中const?QString轉(zhuǎn)換?char?*可能的坑
一、遇到的問題
現(xiàn)在有一個這樣的需求,需要將const QString 轉(zhuǎn)換成 char *
例如:
const QString q_ip = "192.168.1.1"; const char* kc_ip = q_ip.toStdString().c_str(); //單步調(diào)試顯示的結(jié)果可能會是'\0' char* k_ip = const_cast<char*>(kc_ip);
而當(dāng)我這樣寫時:
std::string str_ip = str.toStdString(); const char* kc_ip = str_ip.c_str(); //kc_ip 是"192.168.1.1" ,printf 輸出也是正常的,不是空
這是由于:
str.toStdString().c_str()中toStdString()是一個臨時std::string變量,而c_str()是指向這個臨時std::string變量的字符串地址,所以傳給c時這個臨時std::string變量已經(jīng)被析構(gòu),其內(nèi)容是空,c_str()自然就是'\0'。不過這種情況在未知情況下發(fā)生,有時直接寫QString::toStdString().c_str() 也是好用的。
這個函數(shù)返回一個與這個QString內(nèi)容相同的std::string對象。注意這個函數(shù)的返回值是一個對象。
二、查閱其他說明
在 C++ 中,函數(shù)返回對象一般是類似下面的代碼:
clazz foo() const { clazz c; c.member = 0; return c; }
clazz foo ( ) const
{
clazz c ;
c . member = 0 ;
return c ;
}注意這里的返回對象,其實(shí)是一個臨時對象。在上面代碼中,雖然我們在函數(shù)體內(nèi)創(chuàng)建了一個clazz的對象c,但返回的并不是“這個”對象,而是由 C++ 創(chuàng)建一個臨時對象,再將這個臨時對象返回。注意這里是“臨時對象”,臨時對象是有生命周期的?!禖++ 程序設(shè)計(jì)語言》第 10 章中寫道,“除非一個臨時對象被約束到某個引用,或者被用于作為命名對象的初始化,否則它將在創(chuàng)建它的那個完整表達(dá)式結(jié)束時銷毀”。所謂“完整表達(dá)式”,是指不是其它表達(dá)式的子表達(dá)式的表達(dá)式。簡單來說,一個完整表達(dá)式的標(biāo)識一般是一個分號。
這句看似繞口的話解釋了之前所有的現(xiàn)象。在第一段代碼中,由于函數(shù)返回一個臨時變量,我們立即調(diào)用了這個臨時對象的c_str()函數(shù)。這一切都沒有問題。之后,完整表達(dá)式結(jié)束(遇到分號),而這個臨時變量沒有賦值給某個引用或用于給某個對象初始化,所以這個臨時變量被立即銷毀。由此對象獲得的c_str()函數(shù)結(jié)果同樣被銷毀,因此發(fā)生段錯誤。在第二段代碼中,這個臨時變量用于給sstr對象初始化,我們之后調(diào)用的是這個新的被初始化完成的對象的函數(shù),也就是正常的。第三段代碼雖然也沒有賦值給某個引用或用于給某個對象初始化,但在str.toStdString().c_str()語句結(jié)束后,表達(dá)式并沒有結(jié)束,而是繼續(xù)執(zhí)行函數(shù)調(diào)用。直到函數(shù)調(diào)用返回,才遇到代表表達(dá)式結(jié)束的分號,此時臨時變量才會銷毀。而這時候我們已經(jīng)成功執(zhí)行了函數(shù)代碼。所以一切都沒有問題。
這種看似奇怪的現(xiàn)象其實(shí)只是一個 C++ 語言的陷阱,甚至與 Qt 沒有一點(diǎn)關(guān)系。同樣類似的陷阱還可能發(fā)生在QString::toUtf8()、QString::toAscii()之類的函數(shù)身上,值得注意!
到此這篇關(guān)于Qt中const QString轉(zhuǎn)換 char *可能的坑的文章就介紹到這了,更多相關(guān)Qt const QString轉(zhuǎn)換 char *內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語言運(yùn)算符的優(yōu)先級和結(jié)合性實(shí)例詳解
本文主要介紹C語言運(yùn)算符的知識,這里對運(yùn)算符的優(yōu)先級和結(jié)合性做出了詳解,并附實(shí)例代碼,希望能幫助有需要的小伙伴2016-07-07
使用C語言實(shí)現(xiàn)最小生成樹求解的簡單方法
這篇文章主要介紹了使用C語言實(shí)現(xiàn)最小生成樹求解的簡單方法,包括Prim算法和Kruskal算法的兩種求解方式,需要的朋友可以參考下2015-08-08
C語言實(shí)現(xiàn)通用數(shù)據(jù)結(jié)構(gòu)之通用鏈表
這篇文章主要為大家詳細(xì)介紹了c語言實(shí)現(xiàn)通用數(shù)據(jù)結(jié)構(gòu)之通用鏈表,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-11-11
C語言關(guān)于include順序不同導(dǎo)致編譯結(jié)果不同的問題
這篇文章主要介紹了在日常調(diào)試C語言中include的順序不同從而影響最后編譯結(jié)果不同的問題,究其原因是寫代碼的習(xí)慣所導(dǎo)致,下面跟小編一起來看看吧2022-04-04
C++模擬實(shí)現(xiàn)STL容器vector的示例代碼
這篇文章主要為大家詳細(xì)介紹了C++如何模擬實(shí)現(xiàn)STL容器vector的相關(guān)資料,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)C++有一定幫助,需要的可以參考一下2022-11-11

