Chủ Nhật, 12 tháng 9, 2010

Chuẩn C++ mới có gì mới? (Phần I)

Chuẩn C++ mới có gì mớiĐược biết đến với cái tên C++ 0x, chuẩn C++ mới hứa hẹn mang đến làn gió mới cho giới phát triển phần mềm.


C++ (đọc là “C plus plus”) có thể nói là một trong những ngôn ngữ lập trình nổi tiếng nhất, có ảnh hưởng lớn cả trong giới công nghiệp lẫn giới học thuật. Hiện có hàng triệu lập trình viên sử dụng C++ để viết phần mềm cho nhiều loại máy móc. Nếu dùng máy tính, hầu như chắc chắn bạn có dùng một chương trình nào đó viết bằng C++. Hàng ngày, hầu như mọi người dùng máy tính và Internet đều có dùng chương trình viết bằng C++. Thậm chí, C++ còn được dùng để viết phần mềm điều khiển cho các thiết bị được cho là không có liên quan gì đến máy tính và lập trình như máy ảnh, thang máy.

Thế giới phần mềm và phần cứng thay đổi nhanh và các ngôn ngữ lập trình phải phát triển để thích ứng. Sau hơn chục năm kể từ chuẩn ISO C++ đầu tiên (C++98, được phê chuẩn năm 1998), một chuẩn mới được biết đến với cái tên C++0x đang chuẩn bị ra mắt. Không như bản cập nhật năm 2003 (thường được gọi là C++03), C++0x là bước thay đổi lớn với nhiều tính năng mới quan trọng.

Thông tin quan trọng cho các nhà phát triển làm việc với C++: các trình biên dịch phổ biến như C++ Builder (phiên bản 2009), Visual C++ (phiên bản 2010) và Gnu C++ (phiên bản 4.3) sẽ hỗ trợ chuẩn C++ mới. Hẳn bạn không muốn ngơ ngác khi nghe đồng nghiệp bàn luận về “lamda” hay “concept”. Giờ là lúc thích hợp để tìm hiểu chuẩn mới.

Những tính năng then chốt
Hai tính năng quan trọng nhất của C++0x là "concept" và xử lý song song.

"Concept" cho phép lập trình viên xác định ràng buộc trên các tham số template, đây là cách thức để định nghĩa rõ ràng những kiểu mà một lớp hay hàm template sẽ chấp nhận.

Ví dụ:
template requires LessThanComparable
const T& min(const T &x, const T &y)
{ return y <>
}
int main()
{
std::thread t(hello); t.join();
}

"Lambda" và "closure" là tính năng nổi bật khác của C++0x. Lambda là một hàm “không tên” được định nghĩa tại nơi nó được gọi.

Ví dụ:
std::vector values = getValues();
std::for_each( values.begin(), values.end(), [](int n) { cout <<>.

myfunc([](int x, int y) -> int {return x+y;} )

Lambda có thể tham chiếu các biến trong phạm vi, ví dụ:

std::vector values = getValues();
int total = 0;
std::for_each( values.begin(), values.end(), [&total](int n) { total += n } );

Việc này được gọi là "sự đóng kín" (closure). Dĩ nhiên, bạn có thể thực hiện tương tự với hàm thông thường, nhưng lambda rõ ràng gọn hơn nhiều.

‘Tham chiếu rvalue’ là một cuộc cách mạng khác tuy khá thầm lặng. Có thể hầu hết người dùng sẽ không nhận biết sự tồn tại của nó, tính năng này cho phép những người thiết kế thư viện tối ưu container và thuật toán. Và các từ khóa mới ‘auto’ và ‘decltype’ cho phép gán kiểu tự động, chẳng hạn gán kiểu của một đối tượng khi khởi tạo. Đây là cách tuyệt vời để trình biên dịch chia sẻ gánh nặng lập trình.

Nhiều quyền hơn
Có các tính năng mới cung cấp cơ chế chuẩn và thống nhất cho việc kiểm soát môi trường biên dịch và thực thi bằng lập trình. Ví dụ, xét trường hợp địa chỉ bộ nhớ. Trong C++03 bạn phải dùng đến các kỹ thuật phụ thuộc nền tảng và trình biên dịch nếu bạn muốn can thiệp địa chỉ mặc định của dữ liệu. C++0x giới thiệu 2 toán tử mới alignof và alignas dùng để truy vấn và can thiệp các yêu cầu địa chỉ dữ liệu,
ví dụ:
alignas (16) class Session
{
long long timestamp;
int authorizations;
bool active;
//...
};
cout<<>< font="">

Nguyên tắc biểu thức hằng của chuẩn C++ hiện tại có nhiều hạn chế. Không giống "const", từ khoá mới "constexpr" đảm bảo biểu thức mà nó định nghĩa có thể được dùng như là biểu thức hằng, ví dụ trong khai báo mảng:

constexpr int f(int x){
return x * x; } //kiểm tra lúc biên dịch bắt buộc
int arr[f(3)]; //OK, kích thước của mảng là 9

Nói chung, "constexpr" báo cho lập trình viên biết một biểu thức hay đối tượng cụ thể được đánh giá và khởi tạo lúc biên dịch, ngược với "const" chỉ phát biểu đối tượng đó sẽ không thay đổi trạng thái sau khi khởi tạo.

C++0x còn có một số tính năng mới khác nhằm làm đơn giản các công việc lập trình đệ quy và giảm thiểu mã lệnh rườm rà.

Tương thích với các chuẩn khác
C++0x tăng tính tương thích với các chuẩn quốc tế độc lập. Các bổ sung đầu tiên được thiết kế trong hợp đồng chặt chẽ với ISO/IEC 9899:1999 Standard C (viết tắt là C99).

Ảnh hưởng của chuẩn Unicode 4.0 gần đây cũng được phản ánh trong C++0x. C++98 định nghĩa một kiểu ký tự đặt tên là wchar_t, kiểu này có kích thước được xác định khi hiện thực. Vào giữa thập niên 1990, người ta nghĩ rằng wchar_t đủ để hỗ trợ Unicode nhưng giờ không còn đúng. Kích thước không xác định của wchar_t không cho phép việc mã hóa UTF hỗ trợ nhiều nền tảng trong C++98. C++0x giải quyết vấn đề này bằng cách đưa ra 2 kiểu ký tự mới có kích thước chuẩn: char16_t và char32_t được thiết kế đặc biệt để hỗ trợ tất cả bộ mã Unicode 4.0 và các lược đồ mã hoá (UTF-8, UTF-16 và UTF-32). Tất nhiên, nó cũng hỗ trợ chuỗi Unicode trong Standard Library.

Chuẩn C99 cũng có giới thiệu kiểu "long long" để xử lý số nguyên 64-bit. C++0x khắc phục sự không tương thích của kiểu này bằng cách đưa "long long"và "unsigned long long" vào danh sách các kiểu cơ bản.

Nguyễn Lê

0 nhận xét:

Đăng nhận xét