Aug 25, 2013

Ép kiểu ngầm định - Implicit conversion

Một buổi chiều dẹp các chuyện linh tinh bên Windows Phone, mình lại có hứng thú viết về cu C++ dấu yêu. Lần này là 1 chủ đề rất là nhỏ: ép kiểu ngầm định (implicit conversion)

Vì sao gọi là nhỏ? Vì nó khá là cổ điển và ít được quan tâm nhiều lắm. Tuy nhiên để tìm hiểu tận gốc vấn đề thì cái này khá là hay ho.

Ép kiểu ngầm định từ T1 sang T2 xảy ra khi trong một biểu thức kiểu T1 được dùng trong ngữ cảnh nó không được chấp nhận, tuy nhiên, ngữ cảnh đó lại chấp nhận kiểu T2.

Ví dụ:

int b = 1.2 + 3.4;

Biểu thức ở đây có kiểu là float, nhưng ngữ cảnh của nó sử dụng lại là kiểu

int
. Và thế là chương trình phải làm một cái gì đó để chuyển đổi giữa kiểu float sang int, tuy nhiên điều này không được người lập trình đề cập, thành ra trình biên dịch sẽ tự làm âm thầm và đó chính là ép kiểu ngầm định .

Đọc cái này. Và ta cần highlight một số đoạn sau.

Standard conversions affect fundamental data types

Điều gì ở đây? Standard conversionfundamental data types .Các kiểu dữ liệu cơ sở đã cung cấp sẵn một số ép kiểu, người lập trình không cần định nghĩa lại. Đồng thời, những phương thức ép kiểu đó đã được nâng lên thành chuẩn. Danh sách các phép ép kiểu chuẩn hóa có trong đây (tài liệu từ MSDN ).

the compiler can signal with a warning. This warning can be avoided with an explicit conversion.

Về cái sự ép kiểu ngầm định có thể xảy ra mất mát thông tin (thử ép biến i = 1000 sang char thì biết), compiler sẽ thông báo với ta về sự mất mát thông tin đó. Tuy nhiên, nếu sử dụng ép kiểu chỉ định (explicit conversion) thì điều này không xảy ra. Lý do? Vì khi đó người lập trình đã chấp nhận mất mát thông tin, bởi chính họ là người đã gõ dòng code đó vào.

Tip nho nhỏ: để bật chế độ kiểu tra ép kiểu ngầm định, dùng option -Wconversion , option -Wall không support chuyện này.

Ép kiểu ngầm định xảy ra khi từ T1 sang T2 khi:

  1. Một biểu thức là tham số đầu vào có kết quả trả về là T1 nhưng tham số lại yêu cầu kiểu T2
  2. Một biểu thức có toán hạng là kiểu T2.
  3. Khởi gán một biến có kiểu T2.
  4. Lệnh return trả về kiểu T2.
  5. Biểu thức dùng trong lệnh switch (với T2 là integral type)
  6. Biểu thức dùng trong các lệnh if và các lệnh lặp. T2 trong trường hợp này là kiểu bool

Đọc tiếp tài liệu bên cpp, ta highlight tiếp phần này:

Implicit conversions also include constructor or operator conversions

Ép kiểu ngầm định cho phép dùng contructor và toán tử ép kiểu để chuyển đổi. Vậy ngoài standard conversions ra, ta còn có cả user-defined conversions. Vì vậy, compiler sẽ có một số nguyên tắc nhằm chọn ra phép biến đổi nào cần dùng:

  • Khi T2 là tham số của constructor hay của hàm chuyển kiểu do người dùng định nghĩa (user-defined conversion function) thì compiler sẽ ưu tiên cho standard conversion
  • Khi T2 và T1 đều là built-in types thì compiler sẽ ưu tiên standard conversions.

Tham khảo:

  1. Implicit cast in cppreference
  2. cplusplus
  3. MSDN