2008-08-28 30 views
27

Câu hỏi liên quan đến Regular cast vs. static_cast vs. dynamic_cast:Kiểu cú pháp đúc C++

Bạn thích kiểu cú pháp nào trong C++?

  • C kiểu cú pháp dàn diễn viên: (int)foo
  • C++ - phong cách cast cú pháp: static_cast<int>(foo)
  • constructor cú pháp: int(foo)

Họ có thể không dịch chính xác các hướng dẫn tương tự (do họ?) nhưng hiệu ứng của chúng phải giống nhau (phải không?).

Nếu bạn chỉ đang truyền giữa các kiểu số tích hợp, tôi thấy cú pháp đúc kiểu C++ quá dài. Là một coder Java cũ, tôi có xu hướng sử dụng cú pháp cast kiểu C thay vào đó, nhưng guru C++ cục bộ của chúng ta nhấn mạnh vào việc sử dụng cú pháp hàm dựng.

Bạn nghĩ sao?

Trả lời

49

Đó là thực hành tốt nhất bao giờ sử dụng C-style phôi vì ba lý do chính:

  • như đã đề cập, không kiểm tra được thực hiện ở đây. Các lập trình viên chỉ đơn giản là không thể biết được của các phôi khác nhau được sử dụng mà làm suy yếu mạnh mẽ gõ
  • các phôi mới là cố ý trực quan nổi bật. Kể từ khi phôi thường tiết lộ một điểm yếu trong mã, nó lập luận rằng làm cho phôi có thể nhìn thấy trong mã là một điều tốt.
  • điều này đặc biệt đúng nếu tìm kiếm phôi bằng công cụ tự động. Việc tìm kiếm phôi kiểu C một cách đáng tin cậy là gần như không thể.

Như palm3D lưu ý:

tôi thấy C++ - cú pháp phong cách dàn diễn viên quá dài dòng.

Đây là cố ý, vì những lý do nêu trên.

Cú pháp hàm tạo (tên chính thức: đúc kiểu hàm) ngữ nghĩa giống như làm diễn viên kiểu C và cũng nên tránh (ngoại trừ các khởi tạo biến trên khai báo), vì lý do tương tự. Có thể gây tranh cãi cho dù điều này có đúng ngay cả đối với các kiểu xác định các hàm tạo tùy chỉnh nhưng trong hiệu quả C++, Meyers lập luận rằng ngay cả trong những trường hợp đó, bạn nên hạn chế sử dụng chúng. Để minh họa:

void f(auto_ptr<int> x); 

f(static_cast<auto_ptr<int> >(new int(5))); // GOOD 
f(auto_ptr<int>(new int(5));    // BAD 

Các static_cast đây sẽ thực sự gọi constructor auto_ptr.

+9

Tôi tự hỏi bạn đã tìm kiếm một đoạn trong mã của bạn bao nhiêu lần công cụ tự động ... – Blindy

+2

@Blindly: nó xảy ra. Tôi đã làm điều đó rồi. Hãy nhớ rằng trong C++, không giống như một số ngôn ngữ khác (Java, C#), bạn thường có thể lập trình mà không có phôi. Mọi diễn viên rõ ràng trong mã của bạn đều là lỗi thiết kế tiềm năng. Việc xác định các phôi trong mã C++ của bạn là một bước quan trọng trong việc tái cấu trúc. Trong C#, tất nhiên nó sẽ vô lý khi tìm kiếm các phôi trong mã - chúng ở khắp mọi nơi! –

+0

@Konrad: Và, tất nhiên, cả Java * và * C# cũng có tương đương 'dynamic_cast' của riêng nó, đó là một dàn diễn viên đặc biệt. – Puppy

1

Cú pháp tạo kiểu C, không kiểm tra lỗi. C++ - cú pháp đúc kiểu, thực hiện một số kiểm tra. Khi sử dụng static_cast, ngay cả khi nó không kiểm tra, ít nhất bạn biết bạn nên cẩn thận ở đây.

+1

'static_cast' luôn kiểm tra xem loại nguồn và đích có tương thích hay không. (Nó không thể bảo vệ người dùng chống lại sai lầm của họ nếu họ chuyển đổi cơ sở sang loại có nguồn gốc mà nó không thực sự có, nhưng đó là lỗi của họ.) –

11

Theo Stroustrup:

Các "kiểu mới phôi" đã được giới thiệu để cung cấp cho các lập trình viên một cơ hội để nêu ý định của họ rõ ràng hơn và cho trình biên dịch để bắt nhiều lỗi.

Vì vậy, thực sự, an toàn vì nó thực hiện kiểm tra biên dịch bổ sung.

1

Đúc kiểu C là cách tồi tệ nhất để thực hiện. Thật khó để nhìn thấy, không thể giải thích được, làm xáo trộn các hành động khác nhau mà không nên bị xáo trộn, và không thể làm mọi thứ mà phôi kiểu C++ có thể làm. Họ thực sự cần phải loại bỏ phôi kiểu C từ ngôn ngữ.

1

Tôi sử dụng static_cast vì hai lý do.

  1. Rõ ràng điều gì đang diễn ra. Tôi không thể đọc qua điều đó mà không nhận ra có một diễn viên đang diễn ra. Với phôi kiểu C, mắt bạn có thể truyền qua nó mà không cần tạm dừng.
  2. Thật dễ dàng để tìm kiếm mọi địa điểm trong mã của tôi nơi tôi đang truyền.
2

Chắc chắn kiểu C++. Việc nhập thêm sẽ giúp bạn không truyền khi bạn không nên :-)

5

Về chủ đề này, tôi đang thực hiện theo các khuyến nghị được thực hiện bởi Scott Meyers (More Effective C++, Mục 2: Ưu tiên phôi kiểu C++).

Tôi đồng ý rằng diễn xuất kiểu C++ là tiết, nhưng đó là những gì tôi thích về chúng: chúng rất dễ phát hiện và chúng làm cho mã dễ đọc hơn (điều quan trọng hơn viết).

Họ cũng buộc bạn phải suy nghĩ về loại dàn diễn viên nào bạn cần và chọn loại dàn diễn viên phù hợp, giảm nguy cơ mắc lỗi. Họ cũng sẽ giúp bạn phát hiện lỗi tại thời gian biên dịch thay vì thời gian chạy.

1

Hiện tại, chúng tôi sử dụng phôi kiểu C ở mọi nơi. Tôi hỏi các khác casting question, và bây giờ tôi thấy lợi thế của việc sử dụng static_cast thay vào đó, nếu không có lý do khác hơn là nó "greppable" (Tôi thích thuật ngữ đó). Có lẽ tôi sẽ bắt đầu sử dụng nó.

Tôi không thích kiểu C++; nó trông quá giống như một cuộc gọi hàm.

+1

trông giống như một cuộc gọi chức năng có thể được tốt đẹp, nó cho phép bạn có chức năng tiện ích mà chia sẻ cùng một phong cách như phổ biến 'lexical_cast' để chuyển đổi từ dây <-> loại số. Nhưng đó chỉ là một ý kiến. –

1

Đi theo kiểu C++ và, tệ hơn, đoạn mã tiết chi tiết xấu xí bao gồm kiểu chữ rõ ràng của C++ sẽ là lời nhắc nhở liên tục về những gì chúng ta biết (tức là truyền rõ ràng là xấu - dẫn đến đồng xu của lời giải thích). Không đi với phong cách C++ nếu bạn muốn nắm vững nghệ thuật theo dõi lỗi thời gian chạy.

1

Cú pháp hàm tạo. C++ là OO, các nhà xây dựng tồn tại, tôi sử dụng chúng. Nếu bạn cảm thấy cần phải chú thích các ctor chuyển đổi này, bạn nên làm điều đó cho mọi loại, không chỉ là những cái được tích hợp sẵn. Có thể bạn sử dụng từ khóa 'tường minh' cho các ctors chuyển đổi nhưng cú pháp máy khách bắt chước chính xác cú pháp ctor cho các kiểu dựng sẵn nào. Bị greppable, điều đó có thể đúng, nhưng điều bất ngờ lớn khi nhập nhiều ký tự giúp tìm kiếm dễ dàng hơn. Tại sao đối xử với những người này là đặc biệt? Nếu bạn đang viết công thức toán học với rất nhiều int/unsigned/... đến và từ đôi/float - đồ họa - và bạn cần phải viết một static_cast mỗi lần, giao diện của công thức bị lộn xộn và rất nhiều không đọc được. Và đó là một trận chiến khó khăn dù sao cũng nhiều lần bạn sẽ chuyển đổi mà thậm chí không nhận ra rằng bạn đang có. Đối với con trỏ downcasting tôi sử dụng static_cast như tất nhiên không có ctor tồn tại theo mặc định mà sẽ làm điều đó.

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