2011-12-08 30 views
7

Tôi có chức năng mẫu sau được sử dụng để kết xuất dữ liệu của bất kỳ loại tiêu chuẩn nào thành luồng đầu ra nhị phân.diễn viên kiểu c vs reinterpret_cast

template<typename T> static void 
dump (const T& v, ostream& o) { 
    o.write (reinterpret_cast<const char*>(&v), sizeof(T)); 
} 

Thay vì reinterpret_cast Tôi cũng có thể sử dụng kiểu C (const char *). Có lý do cụ thể nào để sử dụng reinterpret_cast không? Tôi đọc một vài bài viết khác, nơi reinterpret_cast đã cau mày. Nhưng việc sử dụng ở trên là hợp pháp và không thể được thay thế bằng bất cứ điều gì khác, phải không?

Cảm ơn

+0

Tôi cho rằng bạn biết hậu quả của việc đó (tệp kết quả chỉ có thể được đọc lại bởi chương trình được biên dịch với cùng các tùy chọn với cùng một trình biên dịch trên cùng một kiến ​​trúc). – curiousguy

+0

Ai đó sẽ đấm tôi để nói điều này, nhưng nếu bạn * muốn * sử dụng phôi kiểu C, bạn luôn có thể để lại nhận xét chung chung mà bạn không thể bỏ lỡ. Đã có * một số cách để tìm 'const' của bạn trong C, quá. ¯ | _ (ツ) _ | ¯ Tất nhiên bạn nên để ý đến những nguy hiểm. –

Trả lời

10

Vấn đề với phôi kiểu C là chúng hoạt động rất nhiều. Xem tại đây để được giải thích chi tiết: http://anteru.net/2007/12/18/200/

Bạn nên cố gắng luôn sử dụng C++ - phôi, làm cho cuộc sống dễ dàng hơn trong thời gian dài. Vấn đề chính với phôi kiểu C trong trường hợp này là bạn có thể viết (char*)(&v) trong khi với reinterpret_cast, bạn sẽ cần thêm const_cast, vì vậy nó an toàn hơn một chút. Ngoài ra, bạn có thể dễ dàng tìm thấy reinterpret_cast với một regex, điều này là không thể cho các phôi kiểu C.

+2

Bạn thậm chí không cần một regex toàn diện cho 'reinterpret_cast', một tìm kiếm văn bản đơn giản (tốt ol '" Tìm "trên hầu hết các biên tập viên) là đủ :) –

+3

Args, yes. Tôi bắt đầu mà bạn không thể regex cho một diễn viên kiểu C, và sau đó câu vết thương theo cách khác tròn;) – Anteru

+0

Sẽ muốn tìm tất cả các phôi? – curiousguy

1

reinterpret_cast được cau mày khi được sử dụng để thay thế static_cast hoặc dynamic_cast. Sử dụng nó để thay thế một diễn viên C được khuyến khích.

Các phôi mới có lợi ích hơn phôi kiểu C. Đối với một, bạn có thể giới hạn những gì diễn viên bạn thực sự muốn, cho người khác nó dễ dàng hơn để làm một tìm kiếm văn bản cho các phôi mới hơn cho phôi C.

+1

"_khi tìm kiếm văn bản cho cas mới_" bạn có thường xuyên thực hiện điều đó không? – curiousguy

+0

@curiousguy: Tôi đã thực hiện nó một vài lần. Tôi hầu như không bao giờ quan tâm đến việc tôi có một thứ gì đó từ một diễn viên, nhưng tôi thường quan tâm rằng tôi đã thực hiện một bước cụ thể mà tôi biết là liên quan đến một hoạt động diễn viên. Tôi không tìm kiếm diễn viên, * mỗi người *, tôi đang tìm kiếm một thứ khác mà tôi tình cờ biết sử dụng dàn diễn viên. –

4

Không có sự khác biệt. Trong tình huống nhất định, dàn diễn viên kiểu C chính xác là một "diễn giải lại" -cast.

Lý do bạn nên chọn C++ - kiểu phôi là chúng là rõ ràng về nội dung chúng đang truyền. Một diễn viên kiểu C sẽ luôn cố gắng quay trở lại với số lượng tối đa nếu cần, trong khi kiểu C++ chỉ biên dịch nếu có thể như dự định: một phép đúc tĩnh chỉ thành công nếu một trong hai giá trị có thể chuyển đổi hoặc con trỏ/tham chiếu tương thích, và một const-cast chỉ hoạt động nếu nguồn và đích là các phiên bản đủ điều kiện cv của nhau. Một trạng thái diễn giải lại một cách rõ ràng rằng bạn muốn kiểm tra một biểu diễn nhị phân bên dưới. (Lưu ý rằng các giá trị tái diễn hợp lệ chỉ có giá trị là đến void hoặc char-pointer, trừ khi chúng là một phần của một số thủ thuật lớn hơn.)

+0

"_Lưu ý rằng các thuật toán diễn giải lại hợp lệ duy nhất thường là các giá trị cho void-() pointer_" tại sao bạn muốn truyền tới 'void *'? – curiousguy

+0

@curiousguy: vị trí mới ... –

+0

Bạn không cần 'reinterpret_cast' tại đây; 'static_cast' là tốt. (Tôi đã có thể thích một tiêu chuẩn 'implicit_cast'.) – curiousguy

3

Đúc kiểu C rất nguy hiểm. Vì vậy, phân loại C++ chia phép đúc thành các loại dưới đây dựa trên cách sử dụng thông thường,

dynamic_cast (expression) - Cho phép truyền giữa phân cấp lớp thích hợp.

const_cast (biểu thức) - Bỏ đi const-ness.

static_cast (biểu thức) - Ở mức độ C, nhưng vẫn tôn trọng một số không tương thích giữa các loại và không cho phép.

reinterpret_cast (biểu thức) - Nếu vẫn không đáp ứng yêu cầu, điều này có sẵn. C phong cách đúc nhưng với một cái tên. Vì vậy, nó sẽ dễ dàng tìm thấy nó trong cơ sở mã lớn.

Lưu ý: - Hầu hết "reinterpret_cast" có thể được loại bỏ bằng thiết kế phù hợp. Nói cách khác "reinterpret_cast" là cần thiết có nghĩa là, rất có thể một cái gì đó là sai trong thiết kế.

Cập nhật: Đây phải là tùy chọn cuối cùng và trong trường hợp trên, việc sử dụng là chính xác. Bây giờ đề cập đến reinterpret_cast sẽ cung cấp cho người đọc ấn tượng rằng cố ý các nhà văn đã chọn không để chăm sóc an toàn loại. Nhưng sử dụng cách tạo kiểu c sẽ không tạo ra ấn tượng đó.

+0

Nhưng tôi đoán reinterpret_cast được sử dụng trong đoạn mã trên là rất đơn giản - và không đủ điều kiện cho lưu ý thiết kế lại của bạn? – shekhar

+0

Như tôi đã đề cập, đây phải là tùy chọn cuối cùng và trong trường hợp trên, việc sử dụng là chính xác. Bây giờ đề cập đến reinterpret_cast sẽ cung cấp cho người đọc ấn tượng rằng cố ý các nhà văn đã chọn không để chăm sóc an toàn loại. Nhưng sử dụng cách tạo kiểu c sẽ không tạo ra ấn tượng đó. – rakesh

Các vấn đề liên quan