C 11 在 Qt 5 中的應用

2021-07-09 04:08:49 字數 3815 閱讀 8435

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_assertq_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...