Sự khác biệt giữa đúc kiểu static_cast <> và kiểu C là gì?


Câu trả lời:


217

Các kiểu phôi C ++ được kiểm tra bởi trình biên dịch. Diễn viên kiểu C không và có thể thất bại khi chạy.

Ngoài ra, các kiểu phôi c ++ có thể được tìm kiếm dễ dàng, trong khi thực sự rất khó để tìm kiếm các phôi kiểu c.

Một lợi ích lớn khác là 4 phôi kiểu C ++ khác nhau thể hiện ý định của lập trình viên rõ ràng hơn.

Khi viết C ++, tôi thường sử dụng các C ++ theo kiểu C.


67
Các phôi duy nhất có thể thất bại trong thời gian chạy là dynamic_casts.
R. Martinho Fernandes

12
C ++ reinterpret_cast <T> (U) có thể thất bại trong thời gian chạy gần giống như cách các phôi kiểu C có thể, và tất cả chúng đều hoàn toàn khác với cách mà Dynamic_cast <T> (U) thất bại.
Christopher Smith

20
Cast1 cast C bình thường (int)somethingkhông thể thất bại - hoặc bạn gặp phải lỗi int hoặc trình biên dịch.
Tomáš Zato - Phục hồi Monica

2
Bạn có thể giải thích tại sao phôi C ++ được tìm kiếm dễ dàng hơn phôi C không?
Minh Trần

3
@MinhTran Đối với kiểu C ++, bạn có thể tìm kiếm từ khóa "cast" thông qua các tệp nguồn của mình. Nhưng muốn bạn có thể làm với các diễn viên kiểu c?
huangzonghao

176

Tóm lại :

  1. static_cast<>() cung cấp cho bạn khả năng kiểm tra thời gian biên dịch, dàn diễn viên C-Style thì không.
  2. static_cast<>() dễ đọc hơn và có thể được phát hiện dễ dàng ở bất cứ đâu trong mã nguồn C ++, C_Style cast is'nt.
  3. Ý định được truyền đạt tốt hơn nhiều bằng cách sử dụng phôi C ++.

Giải thích thêm :

Các diễn viên tĩnh thực hiện chuyển đổi giữa các loại tương thích . Nó tương tự như dàn diễn viên theo phong cách C, nhưng hạn chế hơn. Ví dụ, ép kiểu C sẽ cho phép một con trỏ nguyên trỏ đến một char.

char c = 10;       // 1 byte
int *p = (int*)&c; // 4 bytes

Vì điều này dẫn đến một con trỏ 4 byte (một con trỏ tới kiểu dữ liệu 4 byte) trỏ đến 1 byte bộ nhớ được phân bổ, việc ghi vào con trỏ này sẽ gây ra lỗi thời gian chạy hoặc sẽ ghi đè lên một số bộ nhớ liền kề.

*p = 5; // run-time error: stack corruption

Ngược lại với kiểu đúc C, ép kiểu tĩnh sẽ cho phép trình biên dịch kiểm tra xem các kiểu dữ liệu con trỏ và con trỏ có tương thích hay không, cho phép lập trình viên bắt được phép gán con trỏ không chính xác này trong quá trình biên dịch.

int *q = static_cast<int*>(&c); // compile-time error

Bạn cũng có thể kiểm tra trang này để biết thêm lời giải thích về các diễn viên C ++: Bấm vào đây


17
Tôi nghĩ thay vì "con trỏ 4 byte", bạn có nghĩa là "con trỏ tới kiểu dữ liệu 4 byte"
iheanyi

nhưng nó cho phép int q = static_cast <int> (c);
TonyParker

3
@TonyParker Đó là vì không có gì sai với dòng đó.
Braden hay nhất

15

Xem phần so sánh các toán tử đúc C ++ .

Tuy nhiên, sử dụng cùng một cú pháp cho một loạt các hoạt động đúc khác nhau có thể làm cho ý định của lập trình viên không rõ ràng.

Hơn nữa, có thể khó tìm thấy một loại diễn viên cụ thể trong một cơ sở mã lớn.

tính tổng quát của dàn diễn viên theo phong cách C có thể là quá mức cần thiết cho các tình huống mà tất cả những gì cần thiết là một chuyển đổi đơn giản. Khả năng lựa chọn giữa một số toán tử đúc khác nhau có mức độ công suất khác nhau có thể ngăn các lập trình viên vô tình truyền sang một loại không chính xác.


14
struct A {};
struct B : A {};
struct C {}; 

int main()
{
    A* a = new A;    

    int i = 10;

    a = (A*) (&i); // NO ERROR! FAIL!

    //a = static_cast<A*>(&i); ERROR! SMART!

    A* b = new B;

    B* b2 = static_cast<B*>(b); // NO ERROR! SMART!

    C* c = (C*)(b); // NO ERROR! FAIL!

    //C* c = static_cast<C*>(b); ERROR! SMART!
}

5
Bạn có thể vui lòng giải thích thêm câu trả lời của bạn thêm một chút mô tả về giải pháp bạn cung cấp không?
abarisone

1
Tôi nghĩ rằng câu trả lời cho thấy "static_casts" kiểm tra chuyển đổi loại để đảm bảo chúng nằm dọc theo các đường dẫn hợp lệ trong biểu đồ phân cấp. Trong ví dụ cụ thể này, việc truyền từ A * đến B * hoặc B * sang A * được cho phép vì A và B tạo thành một đường dẫn trong biểu đồ phân cấp. C * không nằm trên đường dẫn nên static_cast sẽ tạo ra lỗi thời gian biên dịch. Sidenote: Có thể đáng chú ý rằng việc truyền từ A * sang B * có thể dẫn đến NULL với một Dynamic_cast trong thời gian chạy tùy thuộc vào đối tượng cơ bản thực sự.
Tommy Chen

7

Một bài đăng tuyệt vời giải thích các diễn viên khác nhau trong C / C ++ và những gì diễn viên theo phong cách C thực sự làm: https://anteru.net/blog/2007/12/18/200/index.html

Đúc kiểu C, sử dụng cú pháp biến (loại). Điều tồi tệ nhất từng được phát minh. Điều này cố gắng thực hiện các phôi sau, theo thứ tự sau: (xem thêm Tiêu chuẩn C ++, 5,4 expr.cast đoạn 5)

  1. const_cast
  2. tĩnh_cast
  3. static_cast theo sau là const_cast
  4. reinterpret_cast
  5. reinterpret_castfollowed bởi const_cast

5

static_castkiểm tra tại thời điểm biên dịch rằng chuyển đổi không nằm giữa các loại rõ ràng không tương thích. Trái với dynamic_cast, không kiểm tra khả năng tương thích các loại được thực hiện trong thời gian chạy. Ngoài ra, static_castchuyển đổi không nhất thiết phải an toàn.

static_cast được sử dụng để chuyển đổi từ con trỏ sang lớp cơ sở sang con trỏ sang lớp dẫn xuất hoặc giữa các kiểu gốc, chẳng hạn như enum thành int hoặc float sang int.

Người dùng static_castphải đảm bảo rằng việc chuyển đổi là an toàn.

Dàn diễn viên kiểu C không thực hiện bất kỳ kiểm tra nào, cả lúc biên dịch hay lúc chạy.


3

Vì có nhiều kiểu truyền khác nhau, mỗi loại có ngữ nghĩa khác nhau, static_cast <> cho phép bạn nói "Tôi đang thực hiện chuyển đổi hợp pháp từ loại này sang loại khác" như từ int sang double. Một dàn diễn viên kiểu C đơn giản có thể có nhiều ý nghĩa. Bạn đang lên / xuống đúc? Bạn đang diễn giải lại một con trỏ?

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.