Bài giảng Kỹ thuật lập trình - Bài 13: C++11 - Đào Trung Kiên

Tài liệu Bài giảng Kỹ thuật lập trình - Bài 13: C++11 - Đào Trung Kiên: EE3490: Kỹ thuật lập trình – HK1 2017/2018 TS. Đào Trung Kiên – ĐH Bách khoa Hà Nội Bài 13: C++11 1 EE3490: Kỹ thuật lập trình – HK1 2017/2018 TS. Đào Trung Kiên – ĐH Bách khoa Hà Nội Các phiên bản C++  C++98 (đã học trong các bài trước):  Được ISO chuẩn hoá lần đầu tiên  C++03:  Một số thay đổi nhỏ  C++0x / C++11:  Rất nhiều cập nhật mới  Nhiều tính năng được lấy lại từ thư viện boost  C++14:  Một số mở rộng so với C++11  C++17:  Đang thảo luận 2 EE3490: Kỹ thuật lập trình – HK1 2017/2018 TS. Đào Trung Kiên – ĐH Bách khoa Hà Nội Tự suy đoán kiểu  Ví dụ: map> m; // map>::iterator itr = m.begin(); auto itr = m.begin(); // pair& a = m["KTLT"]; auto& a = m["KTLT"]; // pair b; decltype(a) b; 3 EE3490: Kỹ thuật lập trình – HK1 2017/2018 TS. Đào Trung Kiên – ĐH Bách khoa Hà Nội Vòng lặp for theo khoảng (range-based for loop) double a[10]; list l; vector v; for (int x : a) { //... } for (string& x : l) { //... } for (complex& x : v)...

pdf23 trang | Chia sẻ: putihuynh11 | Lượt xem: 774 | Lượt tải: 0download
Bạn đang xem trước 20 trang mẫu tài liệu Bài giảng Kỹ thuật lập trình - Bài 13: C++11 - Đào Trung Kiên, để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên
EE3490: Kỹ thuật lập trình – HK1 2017/2018 TS. Đào Trung Kiên – ĐH Bách khoa Hà Nội Bài 13: C++11 1 EE3490: Kỹ thuật lập trình – HK1 2017/2018 TS. Đào Trung Kiên – ĐH Bách khoa Hà Nội Các phiên bản C++  C++98 (đã học trong các bài trước):  Được ISO chuẩn hoá lần đầu tiên  C++03:  Một số thay đổi nhỏ  C++0x / C++11:  Rất nhiều cập nhật mới  Nhiều tính năng được lấy lại từ thư viện boost  C++14:  Một số mở rộng so với C++11  C++17:  Đang thảo luận 2 EE3490: Kỹ thuật lập trình – HK1 2017/2018 TS. Đào Trung Kiên – ĐH Bách khoa Hà Nội Tự suy đoán kiểu  Ví dụ: map> m; // map>::iterator itr = m.begin(); auto itr = m.begin(); // pair& a = m["KTLT"]; auto& a = m["KTLT"]; // pair b; decltype(a) b; 3 EE3490: Kỹ thuật lập trình – HK1 2017/2018 TS. Đào Trung Kiên – ĐH Bách khoa Hà Nội Vòng lặp for theo khoảng (range-based for loop) double a[10]; list l; vector v; for (int x : a) { //... } for (string& x : l) { //... } for (complex& x : v) { //... } 4 EE3490: Kỹ thuật lập trình – HK1 2017/2018 TS. Đào Trung Kiên – ĐH Bách khoa Hà Nội Con trỏ thông minh (smart pointers)  Là kiểu trừu tượng cho phép mô phỏng các con trỏ, nhưng bổ sung thêm một số tính năng khác:  Quản lý bộ nhớ tự động  Kiểm tra phạm vi  Ví dụ: shared_ptr p1(new int(10)); shared_ptr p2 = p1; *p2 = 20; // bộ nhớ sẽ được thu hồi khi // tham chiếu cuối cùng được huỷ 5 EE3490: Kỹ thuật lập trình – HK1 2017/2018 TS. Đào Trung Kiên – ĐH Bách khoa Hà Nội Đa luồng (multithreading) & Lập trình song song (concurrency) 6 EE3490: Kỹ thuật lập trình – HK1 2017/2018 TS. Đào Trung Kiên – ĐH Bách khoa Hà Nội Luồng (threads)  Cho phép thực thi các nhiệm vụ đồng thời (song song, không đồng bộ), chú ý phân biệt luồng và tiến trình (process)  Luôn có ít nhất một luồng trong chương trình, được tạo cho hàm main: được gọi là luồng chính  Trước C++11, các luồng được quản lý bởi các thư viện ngoài:  POSIX thread (pthread)  Windows API  OpenMP  MPI  Từ C++11, đa luồng là một tính năng có sẵn  #include  Lớp std::thread  Mỗi luồng được thực thi trong một hàm gọi là thread function 7 EE3490: Kỹ thuật lập trình – HK1 2017/2018 TS. Đào Trung Kiên – ĐH Bách khoa Hà Nội Ví dụ #include #include #include using namespace std; void task1() { for (int i = 0; i < 100; i++) { this_thread::sleep_for( chrono::milliseconds(100)); cout << "Thread 1\n"; } } void task2() { for (int i = 0; i < 100; i++) { this_thread::sleep_for( chrono::milliseconds(100)); cout << "Thread 2\n"; } } void main() { thread t(task1); task2(); t.join(); } 8 EE3490: Kỹ thuật lập trình – HK1 2017/2018 TS. Đào Trung Kiên – ĐH Bách khoa Hà Nội Luồng với tham số #include #include #include using namespace std; void task(int* n) { int i, t; for (i=0; i<100; i++) { t = *n; this_thread::sleep_for( chrono::milliseconds(1)); *n = t + 1; } } void main() { thread a[10]; int i, n = 0; for (i=0; i<10; i++) a[i] = thread( task, &n); for (i=0; i<10; i++) a[i].join(); cout << n << endl; } 9 EE3490: Kỹ thuật lập trình – HK1 2017/2018 TS. Đào Trung Kiên – ĐH Bách khoa Hà Nội Critical sections & quản lý sử dụng tài nguyên  Các luồng trong cùng một process chia sẻ bộ nhớ  Một luồng có thể sử dụng bộ nhớ được cấp phát từ các luồng khác  Việc cập nhật các biến chung từ các luồng khác nhau có thể dẫn đến kết quả không mong muốn 10 Luồng 2 t = i; t ++; i = t; Luồng 1 t = i; t ++; i = t; Giá trị i = 10 t#1 = 10 t#2 = 10 t#1 = 11 t#2 = 11 i = 11 i = 11  Việc sử dụng tài nguyên phải được quản lý  Critical sections  Các tài nguyên có thể được hiểu theo nghĩa rộng EE3490: Kỹ thuật lập trình – HK1 2017/2018 TS. Đào Trung Kiên – ĐH Bách khoa Hà Nội Lớp mutex  Mutex = mutual exclusion (loại trừ lẫn nhau)  không quá 1 luồng thực thi đoạn mã ở một thời điểm 11 #include mutex m; void task(int* n) { int i, t; for (i=0; i<100; i++) { m.lock(); t = *n; this_thread::sleep_for(chrono::milliseconds(1)); *n = t + 1; m.unlock(); } } critical section EE3490: Kỹ thuật lập trình – HK1 2017/2018 TS. Đào Trung Kiên – ĐH Bách khoa Hà Nội Lớp parallel_for  Duyệt các phần tử và thực thi một hàm cho trước một cách song song (tối ưu theo số CPU của máy) 12 #include #include #include #include #include using namespace std; using namespace concurrency; int n = 0; mutex m; void task(int itr) { for (int i=0; i<100; i++) { m.lock(); int t = n; this_thread::sleep_for( chrono::milliseconds(1)); n = t + 1; m.unlock(); } } void main() { parallel_for(0, 10, task); cout << n << endl; } EE3490: Kỹ thuật lập trình – HK1 2017/2018 TS. Đào Trung Kiên – ĐH Bách khoa Hà Nội Hàm lambda 13 EE3490: Kỹ thuật lập trình – HK1 2017/2018 TS. Đào Trung Kiên – ĐH Bách khoa Hà Nội Khái niệm  Còn gọi là hàm không tên, được định nghĩa trong các câu lệnh  Thường được dùng như tham số khi gọi các hàm khác  Có thể được chuyển kiểu thành hàm thông thường khi không có “capture” nào  Cú pháp: [các-capture](các-tham-số) -> kiểu-trả-về { thực-thi }  các-capture: danh sách các biến thuộc phạm vi định nghĩa được sử dụng trong hàm, phân cách bằng dấu “,”. Ví dụ:  [a, &b, c, &d]: a và c bằng giá trị, b và d bằng tham chiếu  [&, a, b]: a và b bằng giá trị, còn lại bằng tham chiếu  [=, &a, &b]: a và b bằng tham chiếu, còn lại bằng giá trị  kiểu-trả-về: có thể bỏ qua nếu suy luận được 14 EE3490: Kỹ thuật lập trình – HK1 2017/2018 TS. Đào Trung Kiên – ĐH Bách khoa Hà Nội Ví dụ 1 const int n = 10; int x[n] = {...}; std::sort(x, x + n, [](int a, int b) { return abs(a) < abs(b); } );  Viết theo C++98: bool compare(int a, int b) { return abs(a) < abs(b); } std::sort(x, x + n, compare); 15 EE3490: Kỹ thuật lập trình – HK1 2017/2018 TS. Đào Trung Kiên – ĐH Bách khoa Hà Nội Ví dụ 2 int func(int a, function lambda) { return lambda(a); } void main() { int n = 10, m = 20; int p = func(n, [m](int i) { return i*m; }); cout << p << endl; } 16 EE3490: Kỹ thuật lập trình – HK1 2017/2018 TS. Đào Trung Kiên – ĐH Bách khoa Hà Nội parallel_for void main() { int n = 0; mutex m; parallel_for(0, 10, [&m, &n](int itr) { for (int i = 0; i < 100; i++) { m.lock(); int t = n; this_thread::sleep_for(chrono::milliseconds(1)); n = t + 1; m.unlock(); } }); cout << n << endl; } 17 EE3490: Kỹ thuật lập trình – HK1 2017/2018 TS. Đào Trung Kiên – ĐH Bách khoa Hà Nội Tham chiếu rvalue & Ý nghĩa move 18 EE3490: Kỹ thuật lập trình – HK1 2017/2018 TS. Đào Trung Kiên – ĐH Bách khoa Hà Nội Lvalue và rvalue  Mỗi biểu thức C++ là một lvalue hoặc rvalue  Lvalues: các giá trị có thể tham chiếu (những gì có thể lưu giá trị, có thể được đặt ở vế trái của câu lệnh gán)  Rvalues: các giá trị tạm thời không tồn tại sau khi biểu thức dùng nó kết thúc (chỉ được đặt ở vế phải của câu lệnh gán)  Ví dụ:  int i = 100;  const int a = x * y;  int& m = i; 19 EE3490: Kỹ thuật lập trình – HK1 2017/2018 TS. Đào Trung Kiên – ĐH Bách khoa Hà Nội Ý nghĩa move  Xem constructor sao chép của lớp string: string& operator =(const string& str) { // }  Ví dụ sử dụng: s = "abc"; 1. Giải phóng các tài nguyên s sử dụng 2. Sao chép tài nguyên từ đối tượng tạm thời 3. Giải phóng đối tượng tạm, và do đó, giải phóng các tài nguyên nó sử dụng  Không tối ưu về hiệu năng hoạt động! Tại sao không chuyển đổi (move) tài nguyên của các đối tượng cho nhau? 20 EE3490: Kỹ thuật lập trình – HK1 2017/2018 TS. Đào Trung Kiên – ĐH Bách khoa Hà Nội Tham chiếu rvalue  Tham chiếu rvalue (string&&) là các tham chiếu tới rvalue, được dùng trong quá trình move  s = "abc";  s = s1 + s2;  string ss(s1 + s2);  “Tham chiếu truyền thống” (string&) nay được gọi là tham chiếu lvalue, được sử dụng trong quá trình copy  s = s1;  string ss(s1);  Ta cần phải định nghĩa thêm:  1 toán tử gán move (bên cạnh toán tử gán copy)  1 constructor move (bên cạnh constructor copy) 21 EE3490: Kỹ thuật lập trình – HK1 2017/2018 TS. Đào Trung Kiên – ĐH Bách khoa Hà Nội Các constructor copy và move class string { protected: char* p; public: string(const string& s) { //... (as before) } string(const string&& s) { p = s.p; } }; 22 EE3490: Kỹ thuật lập trình – HK1 2017/2018 TS. Đào Trung Kiên – ĐH Bách khoa Hà Nội Các toán tử gán copy và move class string { protected: char* p; public: string& operator =(const string& s) { //... (as before) } string& operator =(const string&& s) { p = s.p; return *this; } }; 23

Các file đính kèm theo tài liệu này:

  • pdfbai_giang_ky_thuat_lap_trinh_ts_dao_trung_kien_13_c_c_11_1962_1985325.pdf