2008-10-06 32 views
40

Không thể nghi ngờ, tôi sẽ chọn sử dụng STL cho hầu hết các dự án lập trình C++. Câu hỏi được đưa ra cho tôi gần đây, tuy nhiên, "Có trường hợp nào mà bạn không sử dụng STL không?" ...Để STL hoặc! STL, đó là câu hỏi

Tôi càng nghĩ về điều đó, tôi càng nhận ra rằng có lẽ có trường hợp tôi chọn không sử dụng STL ... Ví dụ, một dự án thực sự lớn, dài hạn có codebase dự kiến ​​sẽ kéo dài trong năm ... Có lẽ một giải pháp container tùy chỉnh phù hợp chính xác với các dự án cần có giá trị ban đầu? Bạn nghĩ gì, có trường hợp nào bạn chọn KHÔNG cho STL không?

Trả lời

29

Các dự án có yêu cầu bộ nhớ nghiêm ngặt như đối với các hệ thống nhúng có thể không phù hợp với STL, vì có thể khó kiểm soát và quản lý những gì được lấy từ và quay trở lại vùng heap. Như Evan đã đề cập, việc viết các trình phân bổ thích hợp có thể giúp với điều này, nhưng nếu bạn đếm từng byte được sử dụng hoặc liên quan đến phân mảnh bộ nhớ, nó có thể khôn ngoan hơn để cuộn một giải pháp phù hợp với vấn đề cụ thể của bạn, vì STL đã được tối ưu hóa để sử dụng chung nhất.

Bạn cũng có thể chọn không sử dụng STL cho một trường hợp cụ thể vì có nhiều vùng chứa hiện hành hơn không có trong tiêu chuẩn hiện tại, chẳng hạn như boost :: array hoặc boost :: unordered_map.

+2

Tôi luôn thấy rằng các hộp chứa SDL đều khá nhẹ. Kiểm tra việc triển khai STL của bạn để xem chúng thực sự sử dụng bao nhiêu bộ nhớ. – Albert

+0

Khá. Nếu STL làm những gì bạn muốn, hãy sử dụng nó. Khi nó không còn làm những gì bạn muốn, đó là khi bạn nên xem xét không sử dụng nó. – beldaz

15

Thông thường, tôi thấy rằng đặt cược tốt nhất là sử dụng STL với các bộ phân bổ tùy chỉnh thay vì thay thế các hộp chứa STL bằng các hộp được cuộn tay. Điều tốt đẹp về STL là bạn chỉ trả tiền cho những gì bạn sử dụng.

6

Tôi nghĩ đây là kịch bản điển hình khi mua và mua. Tuy nhiên, tôi nghĩ rằng trong trường hợp này tôi gần như luôn luôn 'mua', và sử dụng STL - hoặc một giải pháp tốt hơn (một cái gì đó từ Boost có lẽ), trước khi lăn của riêng tôi. Bạn nên tập trung hầu hết nỗ lực của mình vào những gì ứng dụng của bạn làm, không phải khối xây dựng nó sử dụng.

45

Những lý do chính không sử dụng STL là rằng:

  1. C++ của bạn thực hiện là cũ và có mẫu hỗ trợ khủng khiếp.
  2. Bạn không thể sử dụng phân bổ bộ nhớ động.

Cả hai đều là những yêu cầu rất hiếm trong thực tế.

Đối với một dự án dài hạn, các thùng chứa của riêng bạn chồng chéo trong chức năng với STL sẽ chỉ tăng chi phí bảo trì và phát triển.

+1

Đây là những gì nó đi xuống. – Christopher

+0

Trong khi tôi đồng ý, tôi cũng sẽ ném đồng thời như một lý do không sử dụng các thùng chứa. Tuy nhiên, tôi sẽ sử dụng chúng cho bất kỳ tài nguyên không được chia sẻ nào. –

+6

Greg - (1) có lẽ rất không phổ biến, nhưng (2) có tính huống rất cao. Trong một số môi trường phát triển nhất định (ví dụ: nền tảng nhúng và hệ thống thời gian thực), phân bổ động bị cấm hoặc không được khuyến khích nhiều. Họ có thể không phải là môi trường lớn, nhưng trong môi trường nó là phổ quát. – Tom

6

Tôi thực sự không nghĩ vậy. Trong việc tạo ra các thùng chứa của riêng tôi, tôi thậm chí sẽ cố gắng để làm cho những người tương thích với STL vì sức mạnh của các thuật toán chung là quá lớn để bỏ cuộc. STL ít nhất nên được sử dụng theo danh nghĩa, ngay cả khi tất cả những gì bạn làm là viết vùng chứa của riêng bạn và chuyên về mọi thuật toán cho nó. Bằng cách đó, mọi thuật toán sắp xếp có thể được gọi là sắp xếp (c.begin(), c.end()). Nếu bạn chuyên sắp xếp để có tác dụng tương tự, ngay cả khi nó hoạt động khác nhau.

2

Tôi đã tìm thấy sự cố khi sử dụng STL trong mã đa luồng. Thậm chí nếu bạn không chia sẻ các đối tượng STL qua các chủ đề, nhiều triển khai sử dụng các cấu trúc an toàn không phải luồng (như ++ để đếm tham chiếu thay vì một kiểu tăng xen kẽ hoặc có các trình cấp phát không an toàn).

Trong mỗi trường hợp này, tôi vẫn chọn sử dụng STL và khắc phục sự cố (có đủ móc để nhận được những gì bạn muốn). Ngay cả khi bạn chọn tạo bộ sưu tập của riêng mình, bạn nên theo dõi kiểu STL cho các trình vòng lặp để bạn có thể sử dụng các thuật toán và các hàm STL khác chỉ hoạt động trên các trình vòng lặp.

+1

Tôi không hiểu. Nếu các đối tượng STL của bạn không được chia sẻ qua các luồng, tại sao nó lại quan trọng có nên sử dụng số gia tăng lồng nhau không? – Ferruccio

+1

Bạn có thể sử dụng VC++ 6.0 không? Phiên bản đó có một sự thực thi STL bị hỏng khi nói đến sự an toàn của luồng. –

+0

Có - nhưng đó không phải là duy nhất. Trên Solaris và HP - Tôi gặp phải các vấn đề tương tự. –

26

Chỉ có rất nhiều lợi thế khi sử dụng stl. Đối với một dự án dài hạn, lợi ích lớn hơn chi phí.

  1. Người lập trình mới có thể hiểu các thùng chứa từ ngày đầu cho họ thêm thời gian để tìm hiểu mã khác trong dự án. (giả sử họ đã biết STL giống như bất kỳ lập trình viên C++ nào có thẩm quyền sẽ)
  2. Sửa lỗi trong các thùng chứa hút và lãng phí thời gian có thể được dùng để nâng cao logic nghiệp vụ.
  3. Rất có thể bạn sẽ không viết chúng cũng như STL được triển khai.

Điều đó đang được nói, các thùng chứa STL không xử lý đồng thời cả. Vì vậy, trong một môi trường mà bạn cần đồng thời, tôi sẽ sử dụng các thùng chứa khác như thùng chứa đồng thời TBB của Intel. Đây là những tiên tiến hơn bằng cách sử dụng khóa hạt mịn như vậy mà các chủ đề khác nhau có thể được sửa đổi container đồng thời và bạn không cần phải serialize quyền truy cập vào container.

+1

Sửa lỗi vùng chứa là * vui vẻ *! Tôi chân thành không đồng ý với khẳng định # 2. (Tuy nhiên, tôi thực sự đồng ý với # 1 từ một ít kinh nghiệm.) – Philip

4

Hầu hết các dự án tôi đã làm việc đều có cách mã hóa cũ hơn bất kỳ phiên bản STL thực sự có thể sử dụng nào - do đó chúng tôi đã chọn không giới thiệu nó ngay bây giờ.

+0

Tại sao? Bạn đã quyết định sử dụng một trình biên dịch cũ không hoạt động với STL? – beldaz

+0

@ beldaz: Không. Chúng tôi đã có bộ sưu tập tại nhà và các lớp chuỗi và trộn chúng với STL sẽ có ý nghĩa rất ít. Viết lại tất cả mọi thứ để sử dụng STL sẽ được tốt đẹp trong lý thuyết nhưng không có trường hợp kinh doanh để hỗ trợ dự án như vậy. –

+0

Trường hợp thú vị, tôi có thể biết bạn đến từ đâu. Không nhiều bạn có thể làm ở đó. – beldaz

2

Vấn đề chính mà tôi đã thấy là phải tích hợp với mã kế thừa dựa trên toán tử không ném mới.

1

Tôi bắt đầu lập trình C trở lại vào khoảng năm 1984 hoặc lâu hơn và chưa bao giờ sử dụng STL. Trong những năm qua tôi đã cuộn thư viện chức năng của riêng tôi và họ đã phát triển và phát triển khi STL không ổn định và hoặc thiếu hỗ trợ nền tảng chéo. Thư viện phổ biến của tôi đã phát triển để bao gồm mã của những người khác (chủ yếu là những thứ như libjpeg, libpng, ffmpeg, mysql) và một vài người khác và tôi thà giữ số lượng mã bên ngoài ở mức tối thiểu. Tôi chắc chắn bây giờ STL là tuyệt vời nhưng thẳng thắn tôi hài lòng với các mục trong hộp công cụ của tôi và thấy không cần thiết vào thời điểm này để tải nó lên với nhiều công cụ hơn. Nhưng tôi chắc chắn thấy những bước nhảy vọt tuyệt vời mà các lập trình viên mới có thể thực hiện bằng cách sử dụng STL mà không phải mã hóa tất cả từ đầu.

+3

Chỉ một câu hỏi: Bạn có đang viết mã bằng C, hoặc bằng C++ không? – paercebal

+4

STL không phải là mã bên ngoài. Nó là một phần tiêu chuẩn được cung cấp bởi tất cả các trình biên dịch C++ phù hợp tiêu chuẩn. Do hộp công cụ của bạn dường như đã hơn mười năm lỗi thời, có thể đáng để bạn nhìn xung quanh và thấy những tiến bộ khác đã được thực hiện. Được rồi, tôi đang nói đùa ở đây, và tôi biết EA có hoặc có một sự ác cảm chính đáng với STL. Nhưng bạn bị nhầm lẫn trong việc mô tả STL là "bên ngoài". – ChrisInEdmonton

3

Một tình huống mà điều này có thể xảy ra là khi bạn đã sử dụng thư viện bên ngoài đã cung cấp khả năng bạn cần từ STL. Ví dụ, công ty của tôi phát triển một ứng dụng trong các lĩnh vực không gian hạn chế, và đã sử dụng Qt cho bộ công cụ cửa sổ. Vì Qt cung cấp các lớp container giống như STL, chúng tôi sử dụng chúng thay vì thêm STL vào dự án của chúng tôi.

+2

Cho rằng STL được bao gồm như là một phần tiêu chuẩn của C++, tuy nhiên, nó không phải là quá nhiều mà bạn không thêm STL vào dự án của bạn mà là, bạn đã chọn không tận dụng lợi thế của một cái gì đó đã có. Mà là tốt. – ChrisInEdmonton

5

Mã hóa cho Symbian.

STLPort hỗ trợ Symbian 9, vì vậy trường hợp chống lại việc sử dụng STL yếu hơn trước đây (không có sẵn) là một trường hợp khá thuyết phục), nhưng STL vẫn còn xa lạ với tất cả các thư viện Symbian. rắc rối hơn là chỉ làm những việc theo cách của Symbian.

Tất nhiên, có thể lập luận rằng những lý do mã hóa cho Symbian không phải là "một dự án lập trình C++".

+0

API Symbian khiến tôi tin rằng họ không hiểu cả C++ lẫn phát triển phần mềm di động. – MSalters

+1

Tôi sẽ không đặc biệt bảo vệ nó, khác hơn là để nói rằng nó là 10 tuổi trở lên, và dường như đã được thiết kế cho các thiết bị khó khăn hơn nhiều so với những gì nó thực sự được sử dụng trên. Ngay cả Nokia đã sử dụng S40 trên các thiết bị cấp thấp của họ, nâng cao câu hỏi về lý do tại sao SymbianOS đưa ra các giả định như vậy. –

+0

Ví dụ, trên một chiếc điện thoại thông minh RAM 32MB, với tư cách là một lập trình viên, tôi không muốn làm thêm việc để tránh chi phí cho bộ nhớ chuỗi 4 byte. Tôi đoán rằng có thể có ý nghĩa tại thời điểm đó, mặc dù. Và họ đối xử với C++ chủ yếu là C với các lớp học, mà không được ưa chuộng trong những ngày này. –

1

Chuẩn C++ cho phép thực thi một số số iterator operations to throw exceptions. Khả năng đó có thể có vấn đề trong một số trường hợp. Do đó, bạn có thể thực hiện thùng chứa đơn giản của riêng mình, đảm bảo không ném ngoại lệ cho các hoạt động quan trọng.

0

Giới thiệu:

STL là một thư viện lớn, và hữu ích trong nhiều trường hợp, nhưng nó dứt khoát không giải quyết tất cả các tình huống. Trả lời STL hoặc!STL giống như trả lời "STL có đáp ứng nhu cầu của bạn hay không?"

Ưu điểm của STL

  • Trong hầu hết các tình huống, STL có một container phù hợp cho một giải pháp nhất định.
  • Nó cũng là tài liệu
  • Nó cũng được biết (Các lập trình viên thường đã biết điều đó, đi vào một dự án ngắn hơn)
  • Nó được thử nghiệm và ổn định.
  • Đó là crossplatform
  • Nó được bao gồm với mỗi trình biên dịch (không thêm một sự phụ thuộc thư viện 3)
  • STL đã được triển khai và sẵn sàng
  • STL là sáng bóng, ...

Độ tương phản của STL

Nó không có nghĩa là bạn cần một biểu đồ đơn giản, cây đỏ-đen hoặc cơ sở dữ liệu rất phức tạp của các phần tử có AI quản lý truy cập đồng thời thô một máy tính lượng tử. Thực tế là, STL không, và sẽ không bao giờ giải quyết mọi thứ.

Các khía cạnh sau đây chỉ là một vài ví dụ, nhưng về cơ bản chúng là hậu quả của thực tế này: STL là một thư viện thực sự có giới hạn.

  • Exceptions: STL relay trên trường hợp ngoại lệ, vì vậy nếu vì lý do nào bạn không thể chấp nhận trường hợp ngoại lệ (ví dụ an toàn quan trọng), bạn có thể không sử dụng STL. Đúng! ngoại lệ có thể bị vô hiệu hóa, nhưng điều đó không giải quyết được thiết kế của chuyển tiếp STL trên chúng và cuối cùng sẽ mang một sự cố.

  • Cần cụ thể (chưa bao gồm) cấu trúc dữ liệu: đồ thị, cây vv

  • hạn chế đặc biệt phức tạp: Bạn có thể khám phá ra rằng STL chứa mục đích chung là không phải là tối ưu nhất cho mã cổ chai của bạn.

  • Cân nhắc đồng thời: Bạn cần đồng thời và STL không cung cấp những gì bạn cần (ví dụ: khóa người đọc không thể được sử dụng dễ dàng do bi-directional [] operator). Hoặc bạn có thể thiết kế một container lấy lợi ích của đa luồng cho một truy cập/tìm kiếm/chèn/bất cứ điều gì nhanh hơn nhiều.

  • STL cần phải phù hợp với nhu cầu của bạn, nhưng điều ngược lại cũng đúng: Bạn cần đáp ứng nhu cầu của STL. Đừng cố gắng sử dụng std::vector trong bộ điều khiển nhúng được nhúng với bộ nhớ RAM không được quản lý 1K.

  • Khả năng tương thích với các thư viện khác: Có thể vì lý do lịch sử, các thư viện bạn sử dụng không chấp nhận STL (ví dụ: QtWidgets sử dụng chuyên sâu QList của chính nó). Việc chuyển đổi các thùng chứa theo cả hai hướng có thể không phải là giải pháp tốt nhất.


Thực hiện chứa riêng bạn

Sau khi đọc rằng, bạn có thể nghĩ: "Vâng, tôi chắc chắn tôi có thể làm điều gì đó tốt hơn cho trường hợp cụ thể của tôi hơn STL không." CHỜ ĐỢI!

Thực hiện container của bạn một cách chính xác trở nên rất nhanh chóng một nhiệm vụ rất lớn: nó không chỉ về việc thực hiện một cái gì đó làm việc, bạn có thể phải:

  • Document nó sâu sắc, trong đó có giới hạn, thuật toán phức tạp, vv.
  • Expect lỗi, và giải quyết chúng
  • nhu cầu bổ sung Incoming: bạn đã biết, chức năng này mất tích, chuyển đổi giữa các loại vv
  • Sau một thời gian, bạn có thể muốn cấu trúc lại, và thay đổi tất cả các phụ thuộc (quá muộn?)
  • ....

mã sử dụng mà sâu trong các mã như một container dứt khoát là cái gì đó mất nhiều thời gian để thực hiện, và nên mặc dù cẩn thận.


Sử dụng thư viện của bên thứ 3

Không STL không có nghĩa là tùy chỉnh. Có rất nhiều thư viện tốt trong mạng, một số thậm chí với giấy phép nguồn mở dễ dãi.

Thêm hoặc không phải thư viện bên thứ ba bổ sung là một chủ đề khác, nhưng nó đáng được xem xét.