[讀書筆記]Universal References in C++11 part 2: Move semantics, lvalue reference and rvalue reference

上一篇: [insert page=’309′ display=’link’] C++11以前,效能上最大的瓶頸就是程式執行過程中,會產生許多不必要的臨時物件,並進行許多昂貴的複制操作。從上一篇的文章中我們知道,C++11導入『T&&』語意來解決這個問題。或許有人會問,這個問題不是早就有相關機制能夠解決了嗎?將function的傳入參數指定為reference或pointer不是就能避掉無謂複制操作?例如下面實作的三種myCopyFunction,這個函式的主要用途是將傳入的參數copy給global 物件myBackupWidget: class Resource{ public: std::string m_data; }; class Widget{ public: Widget() : m_pHeapStorageResource(nullptr){ } public: Resource* m_pHeapStorageResource; Resource m_stackStorageResource; int m_i; }; static Widget g_myBackupWidget; void myCopyFunc1(Widget param){ g_myBackupWidget.m_pHeapStorageResource = param.m_pHeapStorageResource; g_myBackupWidget.m_stackStorageResource = param.m_stackStorageResource; g_myBackupWidget.m_i … Continued

[讀書筆記]Universal References in C++11 part 1: rvalue and lvalue

參考文章: C++ Rvalue References Explained By Thomas Becker Universal References in C++11 by Scott Meyers   寫在前面: 這個系列的程式碼與例子大多出自以上二篇文章,再加上自己本身的理解所描述而成,因此可能會有謬誤的地方還請見諒。若有什麼意見或想法,非常歡迎討論與指教。 本文開始 首先讓我們來看看下面這一段code: template <typename T> void f(T&& param); 我們知道T&指的pass by eference,但T&&到底是?pass by reference的reference?就語法的理解上,似乎有點不太明確的知道它到底在做什麼,因為C++並沒有這種概念。為了跳脫這個語法表示上理解的困境,我們並不需要糾結於「&」這個語法的意義上,「&&」這東西並不是字面上是pass by reference的reference,就把「&&」他當成新的語意來理解吧! 其實T&&這個語法,是在C++11的時候才導入的,它主要可以解決以下幾個問題: Implementing move semantics Perfect forwarding 這裡先還不用急著理解這二個問題到底是什麼,下面的文章將會入深入的討論。但我們只要先知道:「在解決這二個問題之後,在程式中傳遞參數將能夠省下許多記憶體copy的時間」ーー這件事就行了。簡單來說,就是你的程式會變得更快。它能夠保證讓任何type的參數傳入可以用pass … Continued

[boost] iterator的種類

posted in: boost, C/C++程式設計 | 0

input iterators:在尋訪container的時候,只能做向前循序的input。 output iterators:在尋訪container的時候,只能做向前循序的output。 forward iterators:在尋訪container的時候,能夠向前循序做input及output bidirectional iterators:在尋訪container的時候,能夠向前或者向後循序做input及output 以上幾種iterator對於container中的元素只能做一次操作,bidirectional iterators在循訪之前也必須要先決定向前或向後的方向才行。 random access iterators:可以任意的向前或向後來做尋訪,並對整個container做input或output。也就是說,這個iterator並沒有任何操作上的限制。   參考 : http://www.cplusplus.com/reference/std/iterator/

[Boost] 初探Concept check

posted in: boost, C/C++程式設計, 未分類 | 0

  在繼續往下閱讀之前,請先了解何謂泛型機制中的concept及model相關議題,可以參閱以下文章:侯捷觀點(系列書評 2/2)【Genericity/STL 大系】 重點節錄: 『STL 的六大組件 containers, algorithms, iterators, function objects, allocators, adaptors, 全都是 concepts,實作品如 vector, list, sort(), swap() 等等 templates, … 全都是 models。』 『所謂 concept 和 model 所謂 concept,描述某個抽象型別的條件(或說需求,requirements)。concept 並不是一個 class,也不是一個變數或是一個 template 參數;C++ 語言之中沒有任何東西可以直接代表一個concept。然而,在每一個用到泛型程式設計方法的 C++ 程式中,concept 非常重要。由 concepts … Continued

[Boost] ASIO學習筆記:network basic– UDP Server

posted in: ASIO, boost, C/C++程式設計, Server | 0

UDP  Server跟TCP Server不同,它是屬於connectionless的技術,因此不需要acceptor去跟client建立連線的步驟。我們只需要利用socket去bind特定的port後,就可以接收到資料。 一個Sync socket的流程如下,圖片引用自此: 在ASIO中的Server端程式碼: #include <boost/asio.hpp> #include <boost/shared_ptr.hpp> #include <boost/bind.hpp> #include <iostream> #include <string> #include <boost/thread.hpp> using namespace std; void main(){ boost::system::error_code ec; boost::shared_ptr<boost::asio::io_service> io_service(new boost::asio::io_service); boost::shared_ptr<boost::asio::io_service::strand> strand(new boost::asio::io_service::strand(*io_service)); // boost::shared_ptr< boost::asio::io_service::work > work(new boost::asio::io_service::work( *io_service )); try{ … Continued

[Boost] ASIO學習筆記:network basic– TCP Server

posted in: ASIO, boost, C/C++程式設計, Server | 0

在上一篇[Boost] ASIO學習筆記:network basic – client有展示了該怎麼撰寫一個client去連接一個遠端的Server,而在本篇,將會接著介紹怎麼利用ASIO撰寫一個Server來處理與client端的連接。 首先在Server端開始運行之前,最重要的事便是決定要與哪個port綁定並監聽是否有資料傳送進來。只是,到底什麼是port呢?port是範圍定在0~65535之間的號碼,為Client跟Server之間連接的管道。打個比喻來說:如果ip是電話號碼的話,那麼port便是一個公司(Server)的分機號碼。port所定義的,是Client要打哪個分機號碼才能得公司(Server)所提供的服務。 其中: 0~1023為公認埠(Well Known Ports),通常用於某些特定的系統程序或者是常用的網路協定上。例如80為http、21為ftp、23為telnet…等等。 1024~49151為註冊埠(Registered Ports):理論上要使用該port來提供服務的公司要跟IANA是出申請,但實際上我們也常常拿來做動態或私人用途。 49152~65535為動態和/或私有埠(Dynamic and/or Private Ports):通常是拿來當作臨時或特定客製化的需求時使用。 其實,在撰寫程式的時候,我們可以去監聽任何的port,下圖為TCP Server操作的流程圖(下圖引自wiki,我們可以看到ASIO完全遵照Berkeley sockets API進行封裝): 以下為一個最簡單監聽port 12345的serve程式: #include <boost/asio.hpp> #include <boost/shared_ptr.hpp> #include <boost/bind.hpp> #include <iostream> #include <string> #include <boost/thread.hpp> using namespace std; void onAcceptEvent(boost::system::error_code ec, … Continued

[Boost] ASIO學習筆記:network basic – client

posted in: ASIO, boost, C/C++程式設計, Server, 遊戲 | 0

對於網路程式設計而言,不外乎是server或者是client程式這二種。 而怎麼讓二台遠端的電腦透過網路溝通的程式設計,稱作socket programming。 現在就讓我們先從最基本的client端連接到遠端server的程式開始: #include <boost/asio.hpp> #include <boost/shared_ptr.hpp> #include <iostream> #include <string> using namespace std; int main( int argc, char * argv[] ) { boost::shared_ptr< boost::asio::io_service > io_service(new boost::asio::io_service); boost::asio::ip::tcp::socket sock( *io_service ); boost::asio::ip::tcp::resolver resolver(*io_service); boost::asio::ip::tcp::resolver::query query( “www.yahoo.com.tw”, “80”); boost::asio::ip::tcp::resolver::iterator … Continued

[Boost] ASIO學習筆記:使用strand來serializing thread

posted in: ASIO, boost, C/C++程式設計 | 0

[insert page=’151′ display=’link’],我們知道在多條thread的程式設計中,對於執行的結果我們是無法預期的。雖然使用mutex可以保證thread-safety,但卻無法保證工作能夠照我們所期望的順序執行。 在boost ASIO中提供了strand來解決既能保證thread-safety又能夠讓工作的順序能夠依照post的順序執行。執行並觀察以下的程式結果: boost::mutex global_stream_lock; void WorkerThread( boost::shared_ptr< boost::asio::io_service > io_service ){ global_stream_lock.lock(); std::cout < < “[” << boost::this_thread::get_id() << “] Thread Start” << std::endl; global_stream_lock.unlock(); io_service->run(); global_stream_lock.lock(); std::cout < < “[” << boost::this_thread::get_id() << “] Thread Finish” … Continued

[Boost] ASIO學習筆記:post and dispatch

posted in: ASIO, boost, C/C++程式設計 | 0

對於io_service之中,最重要的莫過於post跟dispatch這二個功能。到底這二個功能有何異同呢? post:指的是將一個工作加入Completion Event Queue裡面dispatch:若是在被run()或poll()所回呼的handler,則馬上執行指派的工作,若是在main()的線程中,則效力與post相同。 試著執行以下程式可以看到二個函式的不同: boost::mutex global_stream_lock; void Dispatch( int x ){ global_stream_lock.lock(); std::cout < < “[” << boost::this_thread::get_id() << “] ” << __FUNCTION__ << ” x = ” << x << std::endl; global_stream_lock.unlock(); } void Post( int x ){ … Continued

[boost]ASIO學習筆記:Sync/Async、Blocking/Non-Blocking IO

posted in: ASIO, boost, C/C++程式設計 | 0

關於四種名詞的詳細內容可以參閱本篇連結 其實這四個名詞在概念上有一些微妙的差別,Sync/Async IO的差別在於程式是否要去等待OS的IO操作結束:在boost中是指io_service選用了run()或者是poll(),會進行kernel context switch到OS kernel來運行。而Blocking/Non-Blocking則是指我們是否要等待程式執行流程中的IO結束才能繼續執行,主要是由application來實作、設計執行的機制。 其實一個程式是不是Sync/Asyn或blocking/non-blocking,其實看的是一段程式碼或者是一個function 通常如果該段程式碼包含while迴圈來判斷某個檔案是狀態,那麼就是blocking,但如果這時候又程式thread來分配該任務的執行,那麼就是non-blocking。 在non-blocking的程式中,如果有牽扯到檔案的讀寫問題,那麼我們就必須在程式中撰寫一些機制去確認該檔案是如已經可以寫入,以必免造成race condition的情況。通常依照不同的作業系統會使用poll、select、epoll、iocp等機制。 關於poll、select、epoll等分別請參閱本篇 在boost::ASIO中,由於為了要達成跨平台,因此在背後實作了Proactor模式來隱藏細節,並以Reactor來實作不同平台的機制。我們可以利用以下的程式碼印出我們的作業系統所採用的是那一種: #include <iostream> #include <string> #include <boost/asio.hpp> int main() { std::string output; #if defined(BOOST_ASIO_HAS_IOCP) output = “iocp” ; #elif defined(BOOST_ASIO_HAS_EPOLL) output = “epoll” ; #elif defined(BOOST_ASIO_HAS_KQUEUE) output = “kqueue” … Continued