日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

C++ 11 在 Qt 5 中的应用

發布時間:2023/12/15 55 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++ 11 在 Qt 5 中的应用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

C++ 11 現在已經是 C++ 標準,也就沒有理由不在新的應用中使用。Qt 4.8 是第一個支持 C++ 11 特性的 Qt 版本,不過這里,我們首先介紹的是,Qt 5 中如何結合使用 C++ 11。至于 Qt 4.8,我們會在后續文章中進行闡述。

顯而易見的是,比起 Qt 4.8,Qt 5 利用了更多的 C++ 11 新特性。下面我們來一個個見識一下:

slot 中使用 Lambda 表達式

Lambda 表達式是 C++ 11 帶來的最激動人心的特性之一(豆子已經在前面幾篇文章中不止一次說這樣的話了 ;-P)。簡而言之,它允許創建匿名函數。匿名函數則允許我們直接將一個函數作為參數傳遞,無需顯式地聲明。

Qt 4.8 實際已經可以使用這個特性。只不過在 Qt 4.8 中,Lambda 表達式只能用在 QtConcurrent 的某些函數。現在,前面我們也介紹過,Qt 5 有新的 signal/slot 語法,Lambda 表達式有了更大的用武之地。回憶一下,在你需要編寫 slot 代碼的時候,即使只有一條語句,你也必須為它單獨建立一個函數。這不是很麻煩嗎?現在,我們有了更好的寫法:

123connect(sender, &Sender::valueChanged, [=](const QString &newValue) {????receiver->updateValue("senderValue", newValue);});

Lambda 表達式現在已經被 MSVC 2010、GCC 4.5 和 clang 3.1 實現。

Unicode 字符串常量

C++ 11 允許你使用?u”HelloWorld”?的形式生成 UTF-16 字符串。Qt 利用這個特性增加了一個新的類QStringLiteral。這個類能夠在編譯時初始化QString,沒有了運行時的時間消耗。

1 QString str = QStringLiteral("HelloWorld");

常量表達式?constexpr

C++ 11 增加了新的關鍵字constexpr,指示某些 inline 函數可以在編譯期運算。在?Qt 5 中,我們引入了Q_DECL_CONSTEXPR宏,當所使用的編譯期支持constexpr時,這個宏可以生成constexpr,否則的話則是空白。

在 Qt 源代碼中,我們也利用這個宏改寫了許多函數,例如:

1234567891011121314151617181920212223enum SomeEnum { Value1, Value2, Value3 };Q_DECLARE_OPERATORS_FOR_FLAGS(QFlags<SomeEnum>)// 上面一句聲明了下述函數:// Q_DECL_CONSTEXPR QFlags<SomeValue> operator|(SomeValue,SomeValue) {...}int someFunction(QFlags<SomeEnum> value) {????switch (value) {????????case SomeEnum::Value1:????????????return 1;????????case SomeEnum::Value2:????????????return 2;????????case SomeEnum::Value1 | SomeEnum::Value3:????????// 這一個 case 僅在 C++ 11 中通過編譯????????// 因為 QFlags 運算符是 constexpr 的,也就是在編譯期即可確定????????// 而在之前版本則必須是 ????????//????????QFlags&lt;SomeValue&gt; operator|(SomeValue,SomeValue)????????// 這會引發一個錯誤,因為 case 語句要求編譯期常量????????????return 3;????????default:????????????return 0;????}}

注意,這里我們在枚舉值前面使用可SomeEnum::前綴,這是 C++ 11 允許的,但是之前版本的 C++ 則不允許。

static_assert

在編譯期使用static_assert檢測問題,可以讓 C++ 11 幫助我們可以組織處更好的錯誤信息。Qt 5 引入了Q_STATIC_ASSERT和Q_STATIC_ASSERT_X兩個宏。當static_assert可用時,這兩個宏將使用static_assert,否則使用一些模板技巧。

為了產生更好的編譯錯誤信息,Qt 在 API 不方便的地方大量使用了宏。

override和final

你遇到過這樣的錯誤嗎?自己定義的函數名看上去同父類的某個函數同名,但卻的確有某些字母打錯了,以至于并沒有覆蓋父類函數,從而讓程序不能正確運行(或者是忘記了那函數名最后面的該死的const)?

現在,你可以選擇在的確需要覆蓋父類虛函數的地方加上Q_DECL_OVERRIDE。如果編譯器支持的話,這個宏將展開為新增加的“override”關鍵字。這樣的話,如果編譯器支持 C++ 11,那么如果是簡單的字母錯誤,你就會得到一個錯誤;當你重構虛函數、卻忘記修改子類時,同樣會引發一個錯誤。

1 2 3 4 5 class MyModel : public QStringListModel { ????//... protected: ???? Qt::ItemFlags flags (const QModelIndex & index) Q_DECL_OVERRIDE; };

注意,上面的flags()函數實際是想覆蓋父類的同名函數,但是我們忘記了一個const,就會出現類似下面的錯誤:

12mymodel.h:15: error: `Qt::ItemFlags MyModel::flags(const QModelIndex&)` marked override, but does not override

如果虛函數不能覆蓋,Qt 也提供了另外一個宏,Q_DECL_FINAL,這個宏展開為final。

deleted 成員

當編譯器支持 deleted 函數時,新增加的宏Q_DECL_DELETE將展開為=delete。這就允許我們能夠為一些常見錯誤提供更好的編譯器錯誤信息。

deleted 函數用于顯式地刪除那些不允許編譯器自動生成的函數(例如默認構造函數、默認拷貝運算符等)。deleted 函數不能被調用,如果被使用的話,將會出現一個編譯器錯誤。

我們可以將其用于Q_DISABLE_COPY宏。在此之前,為了實現同樣的目的,我們的做法是將其聲明為private的。盡管效果相同,但是錯誤信息卻并不友好。

右值引用和移動構造函數

在這里,我假定你明白什么叫做“右值引用”。如果不明白,我們會在后面的文章中詳細說明。Qt 5 已經在內部進行了調整,以便支持移動構造函數。因此,你可以大膽的使用他們了!

結論

對于 C++ 11,MSVC 不需要任何特殊的編譯參數,而 GCC 和 Clang 則需要添加 -std=c++0x。

默認情況下,Qt 5 本身會使用 C++ 11 編譯參數進行編譯(如果可能的話)。

如果你使用的是 qmake,那么,在使用 Qt 5 構建的程序的 .pro 文件中,你需要增加這么一句:

1 CONFIG += c++11

(順便提一句,在 Qt 4 中,如果你需要使用 C++ 11 的新特性,則應該增加gcc:CXXFLAGS += -std=c++0x。具體細節,我們會在后面的文章中說明。)

現在,好好利用 C++ 11 所帶來的新特性吧!私以為,僅僅為了auto這一特性,就應該盡快使用 C++ 11 了!;-p

總結

以上是生活随笔為你收集整理的C++ 11 在 Qt 5 中的应用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。