Bạn đã gắn thẻ điều này với ba ngôn ngữ và câu trả lời thực sự khá khác nhau giữa ba ngôn ngữ. Thảo luận về C ++ ít nhiều cũng ngụ ý thảo luận về các phôi C, và điều đó mang lại (ít nhiều) câu trả lời thứ tư.
Vì đó là vấn đề mà bạn không đề cập rõ ràng, tôi sẽ bắt đầu với C. C casts có một số vấn đề. Một là họ có thể làm bất kỳ một số việc khác nhau. Trong một số trường hợp, dàn diễn viên không làm gì khác hơn là nói với trình biên dịch (về bản chất): "Im đi, tôi biết tôi đang làm gì" - tức là, nó đảm bảo rằng ngay cả khi bạn thực hiện một chuyển đổi có thể gây ra sự cố, trình biên dịch sẽ không cảnh báo bạn về những vấn đề tiềm ẩn đó. Ví dụ char a=(char)123456;
,. Kết quả chính xác của việc triển khai này được xác định (phụ thuộc vào quy mô và tính ký kết củachar
), và ngoại trừ trong những tình huống khá lạ, có lẽ không hữu ích. Các phôi C cũng khác nhau ở việc chúng là thứ chỉ xảy ra tại thời điểm biên dịch (tức là bạn chỉ nói với trình biên dịch cách diễn giải / xử lý một số dữ liệu) hay điều gì đó xảy ra tại thời điểm chạy (ví dụ: một chuyển đổi thực tế từ gấp đôi sang Dài).
C ++ cố gắng giải quyết vấn đề đó ở một mức độ nào đó bằng cách thêm một số toán tử ép kiểu "mới", mỗi toán tử được giới hạn ở chỉ một tập hợp con các khả năng của ép kiểu C. Điều này làm cho việc (ví dụ) vô tình thực hiện một chuyển đổi mà bạn thực sự không có ý định trở nên khó khăn hơn - nếu bạn chỉ có ý định loại bỏ hằng số trên một đối tượng, bạn có thể sử dụng const_cast
và đảm bảo rằng điều duy nhất nó có thể ảnh hưởng là liệu một đối tượng là const
, volatile
hay không. Ngược lại, một static_cast
không được phép ảnh hưởng đến việc một đối tượng là const
hayvolatile
. Tóm lại, bạn có hầu hết các loại khả năng giống nhau, nhưng chúng được phân loại để một kiểu truyền thông thường chỉ có thể thực hiện một loại chuyển đổi, trong đó một kiểu truyền kiểu C có thể thực hiện hai hoặc ba chuyển đổi trong một thao tác. Ngoại lệ chính là bạn có thể sử dụng dynamic_cast
thay cho a static_cast
trong ít nhất một số trường hợp và mặc dù được viết là a dynamic_cast
, nhưng nó thực sự sẽ kết thúc là a static_cast
. Ví dụ: bạn có thể sử dụng dynamic_cast
để truyền lên hoặc xuống một hệ thống phân cấp - nhưng việc ép kiểu "lên" hệ thống phân cấp luôn an toàn, vì vậy nó có thể được thực hiện tĩnh, trong khi việc truyền "xuống" hệ thống phân cấp không nhất thiết phải an toàn vì vậy nó được thực hiện động.
Java và C # giống nhau hơn nhiều. Đặc biệt, với cả hai, việc đúc (hầu như?) Luôn là một hoạt động thời gian chạy. Xét về các toán tử ép kiểu C ++, nó thường gần nhất với a dynamic_cast
về những gì thực sự được thực hiện - tức là, khi bạn cố gắng truyền một đối tượng sang một số loại đích, trình biên dịch sẽ chèn một kiểm tra thời gian chạy để xem liệu chuyển đổi đó có được phép không và ném một ngoại lệ nếu không. Các chi tiết chính xác (ví dụ: tên được sử dụng cho ngoại lệ "bad cast") khác nhau, nhưng nguyên tắc cơ bản hầu như vẫn tương tự (mặc dù, nếu bộ nhớ phục vụ, Java thực hiện các phôi áp dụng cho một số kiểu không phải đối tượng như int
gần với C hơn nhiều phôi - nhưng những loại này hiếm khi được sử dụng đủ đến mức 1) Tôi không nhớ điều đó chắc chắn, và 2) ngay cả khi nó đúng, nó không quan trọng lắm).
Nhìn vào mọi thứ một cách tổng quát hơn, tình huống khá đơn giản (ít nhất là IMO): một dàn diễn viên (rõ ràng là đủ) có nghĩa là bạn đang chuyển đổi thứ gì đó từ loại này sang loại khác. Khi / nếu bạn làm điều đó, nó đặt ra câu hỏi "Tại sao?" Nếu bạn thực sự muốn một cái gì đó là một loại cụ thể, tại sao bạn không xác định nó là loại đó để bắt đầu? Điều đó không có nghĩa là không bao giờ có lý do để thực hiện chuyển đổi như vậy, nhưng bất cứ khi nào nó xảy ra, nó sẽ gợi lên câu hỏi liệu bạn có thể thiết kế lại mã để loại đúng được sử dụng xuyên suốt hay không. Ngay cả những chuyển đổi có vẻ vô hại (ví dụ: giữa số nguyên và dấu phẩy động) cũng nên được kiểm tra kỹ hơn nhiều so với mức bình thường. Bất chấp vẻ ngoài của họtương tự, số nguyên thực sự nên được sử dụng cho các loại sự vật "được đếm" và dấu phẩy động cho các loại thứ "được đo lường". Bỏ qua sự phân biệt là điều dẫn đến một số tuyên bố điên rồ như "một gia đình Mỹ trung bình có 1,8 đứa con." Mặc dù tất cả chúng ta đều có thể thấy điều đó xảy ra như thế nào, nhưng thực tế là không có gia đình nào có 1,8 con. Họ có thể có 1 hoặc có thể có 2 hoặc họ có thể có nhiều hơn thế - nhưng không bao giờ có 1.8.