c++ 11 現在已經是 c++ 標準,也就沒有理由不在新的應用中使用。qt 4.8 是第乙個支援 c++ 11 特性的 qt 版本,不過這裡,我們首先介紹的是,qt 5 中如何結合使用 c++ 11。至於 qt 4.8,我們會在後續文章中進行闡述。
顯而易見的是,比起 qt 4.8,qt 5 利用了更多的 c++ 11 新特性。下面我們來乙個個見識一下:
lambda 表示式是 c++ 11 帶來的最激動人心的特性之一(豆子已經在前面幾篇文章中不止一次說這樣的話了 ;-p)。簡而言之,它允許建立匿名函式。匿名函式則允許我們直接將乙個函式作為引數傳遞,無需顯式地宣告。
qt 4.8 實際已經可以使用這個特性。只不過在 qt 4.8 中,lambda 表示式只能用在 qtconcurrent 的某些函式。現在,前面我們也介紹過,qt 5 有新的 signal/slot 語法,lambda 表示式有了更大的用武之地。回憶一下,在你需要編寫 slot **的時候,即使只有一條語句,你也必須為它單獨建立乙個函式。這不是很麻煩嗎?現在,我們有了更好的寫法:
1
2
3
connect
(sender,&
sender
::valuechanged,[
=](const
qstring
&newvalue))
;
lambda 表示式現在已經被 msvc 2010、gcc 4.5 和 clang 3.1 實現。
c++ 11 允許你使用 u」helloworld」 的形式生成 utf-16 字串。qt 利用這個特性增加了乙個新的類qstringliteral
。這個類能夠在編譯時初始化qstring
,沒有了執行時的時間消耗。
1qstring
str=
qstringliteral
("helloworld");
c++ 11 增加了新的關鍵字constexpr
,指示某些 inline 函式可以在編譯期運算。在 qt 5 中,我們引入了q_decl_constexpr
巨集,當所使用的編譯期支援constexpr
時,這個巨集可以生成constexpr
,否則的話則是空白。
在 qt 源**中,我們也利用這個巨集改寫了許多函式,例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
enum
someenum
;
q_declare_operators_for_flags
(qflags
<
someenum
>
) // 上面一句宣告了下述函式:
// q_decl_constexpr qflagsoperator|(somevalue,somevalue)
intsomefunction
(qflags
<
someenum
>
value
) }
注意,這裡我們在列舉值前面使用可someenum::
字首,這是 c++ 11 允許的,但是之前版本的 c++ 則不允許。
在編譯期使用static_assert
檢測問題,可以讓 c++ 11 幫助我們可以組織處更好的錯誤資訊。qt 5 引入了q_static_assert
和q_static_assert_x
兩個巨集。當static_assert
可用時,這兩個巨集將使用static_assert
,否則使用一些模板技巧。
為了產生更好的編譯錯誤資訊,qt 在 api 不方便的地方大量使用了巨集。
你遇到過這樣的錯誤嗎?自己定義的函式名看上去同父類的某個函式同名,但卻的確有某些字母打錯了,以至於並沒有覆蓋父類函式,從而讓程式不能正確執行(或者是忘記了那函式名最後面的該死的const
)?
現在,你可以選擇在的確需要覆蓋父類虛函式的地方加上q_decl_override
。如果編譯器支援的話,這個巨集將展開為新增加的「override
」關鍵字。這樣的話,如果編譯器支援 c++ 11,那麼如果是簡單的字母錯誤,你就會得到乙個錯誤;當你重構虛函式、卻忘記修改子類時,同樣會引發乙個錯誤。
12
3
4
5
class
mymodel
:public
qstringlistmodel;
注意,上面的flags()
函式實際是想覆蓋父類的同名函式,但是我們忘記了乙個const
,就會出現類似下面的錯誤:
1
2
mymodel.h
:15:error:`
qt::
itemflags
mymodel
::flags
(const
qmodelindex&)
`
marked
override
,but
does
notoverride
如果虛函式不能覆蓋,qt 也提供了另外乙個巨集,q_decl_final
,這個巨集展開為final
。
當編譯器支援 deleted 函式時,新增加的巨集q_decl_delete
將展開為=delete
。這就允許我們能夠為一些常見錯誤提供更好的編譯器錯誤資訊。
deleted 函式用於顯式地刪除那些不允許編譯器自動生成的函式(例如預設建構函式、預設拷貝運算子等)。deleted 函式不能被呼叫,如果被使用的話,將會出現乙個編譯器錯誤。
我們可以將其用於q_disable_copy
巨集。在此之前,為了實現同樣的目的,我們的做法是將其宣告為private
的。儘管效果相同,但是錯誤資訊卻並不友好。
對於 c++ 11,msvc 不需要任何特殊的編譯引數,而 gcc 和 clang 則需要新增 -std=c++0x。
預設情況下,qt 5 本身會使用 c++ 11 編譯引數進行編譯(如果可能的話)。
如果你使用的是 qmake,那麼,在使用 qt 5 構建的程式的 .pro 檔案中,你需要增加這麼一句:
1config+=c
++11
(順便提一句,在 qt 4 中,如果你需要使用 c++ 11 的新特性,則應該增加gcc:cxxflags += -std=c++0x
。具體細節,我們會在後面的文章中說明。)
現在,好好利用 c++ 11 所帶來的新特性吧!私以為,僅僅為了auto
這一特性,就應該盡快使用 c++ 11 了!;-p
Qt5訊號與槽C 11風格連線簡介
最近在論壇上看到了這個方面的問題,詳見這裡。隨後淺淺地學習了一下子,看到了qt官方論壇上給出的說明,覺得c 11的functional連線方法還是比qt4既有的巨集連線方法有很大不同。官方論壇的文件 我們在乙個簡單的dialog中,安排如下幾個訊號與槽 class sstest public qdi...
在qt5中嵌入matplotlib
from matplotlib.backends.backend qt5agg import figurecanvasqtagg as figurecanvas from matplotlib.figure import figure import matplotlib.pyplot as plt ...
在 Qt4 中使用 C 11
原文出處 我們前面介紹了許多 c 11 的優點,而且介紹了如何在 qt 5 中使用 c 11。但是,qt 5 畢竟只是乙個尚未發布的版本,現在,我們要介紹的是,如何在 qt 4 中使用 c 11。現在,我們可以在 qt 4.7 和 4.8 兩個版本中使用 c 11。4.8 則增加了更多關於 c 11...