Đại Học Quốc Gia TPHCM
Trung tâm Nghiên cứu và Đào tạo Thiết kế Vi mạch

Ngôn ngữ

Chào mừng đến với ICDREC [ Đăng nhập ] [ Đăng ký ]

Về C++11

C++11 được biết đến như là một tên khác là c++0x, là sự thay thế cho chuẩn C++03 được công bố năm 2003. C++11 được công bố theo chuẩn ISO ngày 12, tháng 8 năm 2011. C++11 mang lại những cải tiến dựa theo chuẩn C++03, một số thay đổi sẽ được đề cập trong bài viết này.

Sự thay thế của từ khóa auto

Quá trình viết mã dài dòng là tồi tệ. Nó làm cho giảm sự trong sáng của mã chương trình. Vì thế từ khóa auto, chưa được dùng đến trong C, được dùng với ý nghĩa mới trong C++11: Kiểu tự động giảm.

Ví dụ:

1
2
3
4
5
6
// Cách viết C++03
for(std::vector<int>::const_iterator ci = v.begin(); ci != v.end(); ++ci);

// Cách viết C++11
for (auto ci = v.cbegin(); ci != v.cend(); ++ci);
// chú ý: hai phương thức cbegin() và cend() sẽ trả về kiểu const_iterator

Ví dụ cách dùng sai:

1
2
3
4
5
6
7
8
9
10
auto x = 10.0;
// Nếu lập trình viên mới thay đổi '10.0' thành 10, khi đó x sẽ trở thành kiểu số nguyên
// và các đoạn mã phụ thuộc vào nó theo kiểu dấu chấm động sẽ sai.
// Lời khuyên 1: sử dụng auto giảm sự dài dòng, không nhất quán

for
(auto i = 0ul; i < v.size(); ++i);
// Đây là cách viết thông minh của 'unsigned long int i=0'

// Lời khuyên 2: Không sử dụng auto nếu chỉ định kiểu dữ liệu, nó thay đổi mục đích của từ //khóa auto

// Lời khuyên 3: không dùng auto với các hằng

Tầm hoạt động của vòng lặp for()

Vòng lặp iterrator được sử dụng để duyệt qua tất cả nội dung của STL Containers. Đây là một hoạt động phổ biến. C++11 cung cấp cách dùng đặc biệt của for(), có thể duyệt qua tất cả nội dung bắt đầu với phương thức begin() và kết thúc với phương thức end() .
Cách sử dụng này cũng áp dụng được với mảng của C.

Ví dụ:

1
2
3
4
5
6
7
8
9
10
// Theo cách dùng của C++03
for (std::vector<int>::iterator i = v.begin(); i != v.end(); ++i);

// Theo cách dùng của c++11

for (int &item: v);
// item sẽ trở thành thứ tự của nội dung chứa trong biến v
// chú ý: item được dùng là tham biến, nó cho phép thay đổi giá trị của //item

for
(const int &item: v);// Không thể thay đổi item, dùng cách hằng tham biến cho tối ưu tốc
for (int item: v); // Không thể thay đổi item, dùng bằng cách truyền tham trị

Khởi tạo danh sách (lists)

Các kiểu container trong C++03 không khởi tạo một cách tự nhiên như cách khởi tạo mảng của C. Cách khởi tạo này sẽ được thực hiện trong C++11.

Ví dụ:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Mảng C
char array1[] = {'A', 'B'};
double array2[] = {32.0, 6.003, -0.1};

// C++03 vectors

std::vector<char> cpp03vector1;
cpp03vector1.push_back('A');
cpp03vector1.push_back('B');

std::vector<double> cpp03vector2(3);
cpp03vector2[0] = 32.0;
cpp03vector2[1] = 6.003;
cpp03vector2[2] = -0.1;

// C++11 vectors

std::vector<char> cpp11vector1 = {'A', 'B'};
std::vector<double> cpp11vector2 = {32.0, 6.003, -0.1};
// hoặc...
std::vector<char> cpp11vector3{'A', 'B'};
std::vector<double> cpp11vector4{32.0, 6.003, -0.1};
// chú ý cách dùng này sẽ áp dụng cho các kiểu STL container khác
Khởi tạo danh sách (lists) có thể dùng với các cấu trúc phức tạp hơn.

Ví dụ:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <map>
#include <string>
#include <vector>
#include <utility>

using namespace
std;

map<string, vector<pair<string, int>>> name_languages_year {
    {"Dennis Ritchie", {{"B", 1969}, {"C", 1973}}},
    {"Niklaus Wirth", {{"Pascal", 1970}, {"Modula-2", 1973}, {"Oberon", 1986}}},
    {"Bjarne Stroustrup", {{"C++", 1983}}},
    {"Walter Bright", {{"D", 1999}}}
};
// chú ý: danh sách được lồng vào đúng với danh sách mẫu.

cout << name_languages_year["Niklaus Wirth"].at(0).first << endl; // In ra `Pascal'

// Thêm phần tử mới vào map

name_languages_year["John McCarthy"] = {
    {"Lisp", 1958}
};
// notice the lack of explicit types

Mảng trong C++


Đây là một sự bổ sung hơn là cải thiện, nhưng tôi quyết định thêm vào  trong bài viết này.

C++11 cung cấp std::array, mục đích để thay thế cách dùng mảng của C. Nó có kích cỡ được định trước, nhỏ gọn và là một lựa chọn cho cách dùng kích thước thay đổi được trong std::vector.

Ví dụ:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <array>

// Mảng C

char carray1[] = "Abc"; // chú ý: không nhìn thấy '\0' ở cuối mảng

float
carray2[] = {0.2f, 33.33f};
// Mảng C++
std::array<char, 3> cpparray1{{ 'A', 'b', 'c'}};
std::array<float, 2> cpparray2{{0.2f, 33.33f}};
// Quan sát 1: kích thước của mảng được suy ra trong lúc biên dịch
// Quan sát 2: Mảng không thể thay đổi kích thước
// Quan sát 3: dấu ngoặc nhọn là cách khởi tạo tự nhiên của mảng trong C.


// Đây là cách dùng cũ của C khác với new() trong C++


std::cout << sizeof carray1 - 1; // -1 bởi vì trừ ra '\0'
std::cout << sizeof carray2 / sizeof (float); // bởi vì số lượng các thành phần != số byte
std::cout << cpparray1.size();
std::cout << cpparray2.size();

carray2[-5] = 0.1f; // do the moonwalk!
cpparray2.at(-5) = 0.1f; // xảy ra std::out_of_range exception

// Tất nhiên có một số nguyên nhân chỉ rõ lý do mảng của C++ tốt hơn mảng của C
// Nhưng ví dụ này sẽ lớn hơn

Những sửa đổi nhỏ

Những sửa đổi những hạn chế của C++03 trong C++11:
  • std::set<std::vector<int>> biên dịch sau cùng.
    Thông báo việc thiếu giữa hai dấu ngoặc nhọn cuối cùng.
  • std::string có thêm hai phương thức front()back().
  • File streams chấp nhận std::string File ngõ vào.
    Điều này sẽ loại bỏ cách dùng phương thức c_str() .
  • Một số hoán đổi các kiểu số thành std::string có thể dùng như các hàm overloaded:
    std::to_string(int)
    std::to_string(float)
    std::to_string(double)
    ...

Các Trình biên dịch hỗ trợ cho C++11

... Danh sách các trình biên dịch. Nhưng cần 1 hoặc 2 năm để hỗ trợ đầy đủ.
Trình biên dịch C++ của GNU yêu cầu tham số dòng lệnh là -std=c++0x để biên dịch C++11.
Microsoft Visual Studio 2010 Microsoft Visual Studio 201x (v11) hỗ trợ một số tính năng của C++11.
 
 Bản in Bản in Gửi Email cho bạn bè Gửi Email cho bạn bè
⬆ to top