it-swarm-vi.com

Thực tiễn tồi tệ nhất trong C ++, những lỗi phổ biến

Sau khi đọc câu nói nổi tiếng này của Linus Torvalds , tôi tự hỏi thực sự tất cả những cạm bẫy của các lập trình viên trong C++ là gì. Tôi rõ ràng không đề cập đến lỗi chính tả hoặc luồng chương trình xấu như được xử lý trong câu hỏi này và câu trả lời của nó , nhưng với các lỗi cấp cao hơn không được trình biên dịch phát hiện và không dẫn đến lỗi rõ ràng tại Lần chạy đầu tiên, lỗi thiết kế hoàn chỉnh, những điều không thể thực hiện được trong C nhưng có khả năng được thực hiện trong C++ bởi những người mới không hiểu đầy đủ ý nghĩa của mã của họ.

Tôi cũng hoan nghênh các câu trả lời chỉ ra việc giảm hiệu suất rất lớn, nơi nó thường không được mong đợi. Một ví dụ về những gì một trong những giáo sư của tôi đã từng nói với tôi về một trình tạo trình phân tích cú pháp LR (1) mà tôi đã viết:

Bạn đã sử dụng phần nào quá nhiều trường hợp thừa kế và ảo không cần thiết. Kế thừa làm cho một thiết kế phức tạp hơn nhiều (và không hiệu quả do hệ thống con RTTI (suy luận kiểu thời gian chạy)) và do đó, nó chỉ nên được sử dụng khi có ý nghĩa, ví dụ: cho các hành động trong bảng phân tích. Bởi vì bạn sử dụng nhiều mẫu, nên thực tế bạn không cần kế thừa. "

35
Felix Dombek

Torvalds đang nói về mông của mình ở đây.


OK, tại sao anh ta nói ra khỏi mông của mình:

Trước hết, lời nói của anh ta thực sự không có gì là NHƯNG. Có rất ít nội dung thực tế ở đây. Lý do duy nhất khiến nó thực sự nổi tiếng hoặc thậm chí được tôn trọng nhẹ là bởi vì nó được tạo ra bởi Thần Linux. Lập luận chính của anh ta là C++ là tào lao và anh ta thích chọc giận mọi người C++. Tất nhiên không có lý do nào để đáp lại điều đó và bất cứ ai coi đó là một cuộc tranh luận hợp lý dù sao cũng là cuộc trò chuyện.

Đối với những gì có thể được lấp lánh như những điểm khách quan nhất của mình:

  • STL và Boost hoàn toàn tào lao <- sao cũng được. Bạn là một thằng ngốc.
  • STL và Boost gây ra vô số nỗi đau <- nực cười. Rõ ràng là anh ta cố tình quá mức nhưng sau đó tuyên bố thực sự của anh ta ở đây là gì? Tôi không biết. Có một số khó khăn hơn rất nhiều để tìm ra các vấn đề khi bạn khiến trình biên dịch nôn ra trong Spirit hoặc thứ gì đó, nhưng nó không ít nhiều khó khăn để tìm ra việc gỡ lỗi UB do sử dụng sai các cấu trúc C như void *.
  • Các mô hình trừu tượng được khuyến khích bởi C++ là không hiệu quả. <- Thích cái gì? Anh ta không bao giờ mở rộng, không bao giờ cung cấp bất kỳ ví dụ nào về ý nghĩa của anh ta, anh ta chỉ nói điều đó. BFD. Vì tôi không thể nói những gì anh ấy đề cập đến có một chút điểm cố gắng "bác bỏ" tuyên bố. Đó là một câu thần chú phổ biến của C bigots nhưng điều đó không làm cho nó trở nên dễ hiểu hoặc dễ hiểu hơn.
  • Việc sử dụng đúng C++ có nghĩa là bạn giới hạn bản thân ở các khía cạnh C. <- Trên thực tế, mã WORSE C++ hiện có, vì vậy tôi vẫn không biết WTF mà anh ấy đang nói đến.

Về cơ bản, Torvalds đang nói ra khỏi mông của mình. Không có tranh luận dễ hiểu được đưa ra về bất cứ điều gì. Mong đợi một phản bác nghiêm trọng của những điều vô nghĩa như vậy chỉ là ngớ ngẩn đơn giản. Tôi được bảo là "mở rộng" về việc bác bỏ một điều gì đó mà tôi dự kiến ​​sẽ mở rộng nếu đó là nơi tôi đã nói. Nếu bạn thực sự, thành thật nhìn vào những gì Torvalds nói bạn sẽ thấy rằng anh ta thực sự không nói gì.

Chỉ vì Chúa nói rằng điều đó không có nghĩa là nó có ý nghĩa hay nên được thực hiện nghiêm túc hơn so với việc một số bozo ngẫu nhiên nói điều đó. Sự thật mà nói, Thiên Chúa chỉ là một bozo ngẫu nhiên khác.


Trả lời câu hỏi thực tế:

Có lẽ cách thực hành C++ tồi tệ nhất và phổ biến nhất là đối xử với nó như C. Tiếp tục sử dụng các hàm C API như printf, được (cũng bị coi là xấu trong C), strtok, v.v ... không chỉ không tận dụng được sức mạnh được cung cấp bởi hệ thống loại chặt chẽ hơn, chắc chắn chúng sẽ dẫn đến các biến chứng hơn nữa khi cố gắng tương tác với mã C++ "thực". Về cơ bản, hãy làm chính xác điều ngược lại với những gì Torvalds đang khuyên.

Tìm hiểu cách tận dụng STL và Boost để phát hiện thêm các lỗi phát hiện thời gian và để làm cho cuộc sống của bạn dễ dàng hơn theo những cách khác, ví dụ (mã thông báo boost chẳng hạn là loại an toàn VÀ giao diện tốt hơn). Đúng là bạn sẽ phải học cách đọc lỗi mẫu, điều gây khó chịu lúc đầu, nhưng (theo kinh nghiệm của tôi dù sao) nó thực sự dễ dàng hơn nhiều so với cố gắng gỡ lỗi một cái gì đó tạo ra hành vi không xác định trong thời gian chạy, mà C api tạo ra khá dễ làm.

Không phải nói rằng C không tốt bằng. Tôi tất nhiên thích C++ hơn. Lập trình viên C thích C hơn. Có sự đánh đổi và thích chủ quan khi chơi. Cũng có rất nhiều thông tin sai lệch và FUD trôi nổi xung quanh. Tôi sẽ nói rằng có nhiều FUD và thông tin sai lệch trôi nổi về C++ nhưng tôi thiên vị về vấn đề này. Ví dụ, các vấn đề "phình to" và "hiệu suất" C++ được cho là không thực sự là vấn đề lớn trong hầu hết thời gian và chắc chắn bị thổi phồng ra khỏi tỷ lệ của thực tế.

Đối với các vấn đề mà giáo sư của bạn đề cập đến, đây không phải là duy nhất đối với C++. Trong OOP (và trong lập trình chung), bạn muốn thích sáng tác hơn thừa kế. Kế thừa là mối quan hệ ghép nối mạnh nhất có thể tồn tại trong tất cả các ngôn ngữ OO. C++ thêm Một điều nữa là mạnh mẽ hơn, tình bạn. Kế thừa đa hình nên được sử dụng để thể hiện sự trừu tượng và các mối quan hệ "is-a", nó không bao giờ được sử dụng để tái sử dụng. Đây là lỗi lớn thứ hai bạn có thể mắc phải trong C++ và đó là một lỗi khá lớn , nhưng nó khác xa với ngôn ngữ. Bạn có thể tạo các mối quan hệ thừa kế quá phức tạp trong C # hoặc Java, và chúng sẽ có cùng một vấn đề.

69
Edward Strange

Tôi đã luôn nghĩ rằng sự nguy hiểm của C++ đã được cường điệu hóa bởi những người lập trình C thiếu kinh nghiệm.

Đúng, C++ khó nhận hơn một thứ gì đó như Java, nhưng nếu bạn lập trình bằng các kỹ thuật hiện đại thì việc viết các chương trình mạnh mẽ là khá dễ dàng. Thành thật mà nói tôi không có đó việc lập trình thời gian trong C++ khó khăn hơn nhiều so với tôi làm bằng các ngôn ngữ như Java và tôi thường thấy mình thiếu một số trừu tượng C++ như mẫu và RAII khi tôi thiết kế bằng các ngôn ngữ khác .

Điều đó nói rằng, ngay cả sau nhiều năm lập trình trong C++, cứ thỉnh thoảng tôi sẽ phạm một lỗi thực sự ngu ngốc không thể có trong ngôn ngữ cấp cao hơn. Một cạm bẫy phổ biến trong C++ là bỏ qua tuổi thọ của đối tượng: in Java và C # bạn thường không phải quan tâm đến tuổi thọ của đối tượng *, bởi vì tất cả các đối tượng tồn tại trên heap và chúng được quản lý cho bạn bởi một người thu gom rác ma thuật.

Bây giờ, trong C++ hiện đại, thường bạn cũng không cần quan tâm nhiều đến thời gian sống của đối tượng. Bạn có các hàm hủy và các con trỏ thông minh quản lý vòng đời của các đối tượng cho bạn. 99% thời gian, điều này làm việc tuyệt vời. Nhưng thỉnh thoảng, bạn sẽ bị vặn bởi một con trỏ lơ lửng (hoặc tham chiếu.) Ví dụ, gần đây tôi có một đối tượng (hãy gọi nó là Foo) có chứa một biến tham chiếu bên trong cho một đối tượng khác ( hãy gọi nó là Bar). Tại một thời điểm, tôi đã sắp xếp mọi thứ một cách ngu ngốc để Bar đi ra khỏi phạm vi trước khi Foo, nhưng hàm hủy của Foo kết thúc bằng cách gọi hàm thành viên của Bar. Không cần phải nói, mọi thứ đã không diễn ra tốt đẹp.

Bây giờ, tôi không thể đổ lỗi cho C++ vì điều này. Đó là thiết kế tồi của riêng tôi, nhưng vấn đề là loại điều này sẽ không xảy ra trong một ngôn ngữ được quản lý ở cấp độ cao hơn. Ngay cả với con trỏ thông minh và tương tự, đôi khi bạn vẫn cần phải có nhận thức về thời gian sống của đối tượng.


[.__.] * Nếu tài nguyên đang được quản lý là bộ nhớ, nghĩa là như vậy.

19
Charles Salvia

Sử dụng quá mức try/catch khối.

File file("some.txt");
try
{
  /**/

  file.close();
}
catch(std::exception const& e)
{
  file.close();
}

Điều này thường bắt nguồn từ các ngôn ngữ như Java và mọi người sẽ lập luận rằng C++ thiếu mệnh đề finalize.

Nhưng mã này thể hiện hai vấn đề:

  • Bạn cần xây dựng file trước try/catch, vì thực tế bạn không thể close một tệp không tồn tại trong catch. Điều này dẫn đến "rò rỉ phạm vi" trong đó file hiển thị sau khi đã bị đóng. Bạn có thể thêm một khối nhưng ...: /
  • Nếu ai đó đến và thêm return ở giữa phạm vi try, thì tệp không bị đóng (đó là lý do tại sao mọi người chê bai về việc thiếu mệnh đề finalize)

Tuy nhiên, trong C++, chúng tôi có nhiều cách hiệu quả hơn để xử lý vấn đề này:

  • Java finalize
  • using của C #
  • Đi defer

Chúng tôi có RAII, người có tài sản thực sự thú vị được tóm tắt tốt nhất là SBRM (Quản lý tài nguyên giới hạn phạm vi).

Bằng cách tạo lớp để trình hủy của nó dọn sạch các tài nguyên mà nó sở hữu, chúng tôi không đặt trách nhiệm quản lý tài nguyên cho mỗi người dùng của nó!

Đây là tính năng tính năng tôi bỏ lỡ trong bất kỳ ngôn ngữ nào khác và có lẽ là tính năng bị lãng quên nhiều nhất.

Sự thật là hiếm khi cần viết try/catch chặn trong C++, ngoài mức cao nhất để tránh chấm dứt mà không đăng nhập.

13
Matthieu M.

Sự khác biệt trong mã thường liên quan nhiều đến lập trình viên hơn là ngôn ngữ. Đặc biệt, cả lập trình viên C++ giỏi và lập trình viên C đều sẽ có các giải pháp tốt tương tự (ngay cả khi khác nhau). Bây giờ, C là một ngôn ngữ đơn giản hơn (như một ngôn ngữ) và điều đó có nghĩa là có ít trừu tượng hơn và khả năng hiển thị nhiều hơn về những gì mã thực sự làm.

Một phần trong lời ca tụng của anh ta (anh ta được biết đến với những lời ca ngợi chống lại C++) dựa trên thực tế là nhiều người sẽ sử dụng C++ hơn và viết mã mà không thực sự hiểu những gì trừu tượng che giấu và đưa ra các giả định sai.

Một lỗi phổ biến phù hợp với tiêu chí của bạn là không hiểu cách các nhà xây dựng sao chép hoạt động khi xử lý bộ nhớ được phân bổ trong lớp của bạn. Tôi đã mất số lượng thời gian tôi đã dành để khắc phục sự cố hoặc rò rỉ bộ nhớ vì một 'noob' đã đặt các đối tượng của họ vào bản đồ hoặc vectơ và không viết đúng các hàm tạo và hàm hủy.

Thật không may, C++ có đầy đủ các gotchas 'ẩn' như thế này. Nhưng phàn nàn về điều đó cũng giống như phàn nàn bạn đã đến Pháp và không thể hiểu mọi người đang nói gì. Nếu bạn sẽ đến đó, hãy học ngôn ngữ.

9
Henry

C++ cho phép rất nhiều tính năng và phong cách lập trình tuyệt vời, nhưng điều đó không có nghĩa đây thực sự là những cách tốt để sử dụng C++. Và trên thực tế, thật dễ dàng để sử dụng C++ không chính xác.

Nó phải là đã học và hiểu đúng , chỉ học bằng cách thực hiện (hoặc sử dụng nó như người ta sẽ sử dụng một số ngôn ngữ khác) sẽ dẫn đến mã không hiệu quả và dễ bị lỗi.

6
Dario

Chà ... Để bắt đầu, bạn có thể đọc C++ FAQ Lite

Sau đó, một số người đã xây dựng sự nghiệp viết sách về những điều phức tạp của C++:

Herb Sutter Scott Meyers cụ thể là.

Về phần thiếu sót của Torvalds ... hãy nói với mọi người, nghiêm túc: Không có ngôn ngữ nào khác ngoài đó có quá nhiều mực để xử lý các sắc thái của ngôn ngữ. Python & Ruby & Java sách đều tập trung vào viết ứng dụng ... sách C++ của bạn tập trung vào các tính năng ngôn ngữ ngớ ngẩn/mẹo/bẫy.

4
red-dirt

Tạo khuôn quá nặng có thể không dẫn đến lỗi lúc đầu. Tuy nhiên, khi thời gian trôi qua, mọi người sẽ cần phải sửa đổi mã đó và họ sẽ gặp khó khăn khi hiểu một mẫu rất lớn. Đó là khi lỗi xâm nhập - sự hiểu lầm gây ra các bình luận "Nó biên dịch và chạy", điều này thường dẫn đến mã gần như nhưng không hoàn toàn chính xác.

Nói chung nếu tôi thấy mình đang thực hiện một mẫu chung sâu ba cấp, tôi dừng lại và nghĩ làm thế nào nó có thể được giảm xuống một. Thông thường vấn đề được giải quyết bằng cách trích xuất các hàm hoặc các lớp.

3
Michael K

Cảnh báo: đây không phải là một câu trả lời gần như là một bài phê bình về cuộc nói chuyện mà "người dùng không biết" liên quan đến câu trả lời của anh ta.

Điểm chính đầu tiên của anh là "được cho là" tiêu chuẩn luôn thay đổi ". Trong thực tế, các ví dụ anh đưa ra liên quan đến các thay đổi trong C++ trước đó đã có một tiêu chuẩn. Kể từ năm 1998 (khi tiêu chuẩn C++ đầu tiên được hoàn thiện), các thay đổi về ngôn ngữ là khá tối thiểu - trên thực tế, nhiều người sẽ cho rằng vấn đề thực sự là hơn nữa nên thay đổi. Tôi khá chắc chắn rằng tất cả các mã phù hợp với tiêu chuẩn C++ ban đầu vẫn phù hợp với tiêu chuẩn hiện tại. Mặc dù đó là phần nào ít chắc chắn hơn, trừ khi có gì đó thay đổi nhanh chóng (và khá bất ngờ), điều tương tự cũng sẽ khá đúng với tiêu chuẩn C++ sắp tới (về mặt lý thuyết, tất cả mã được sử dụng export sẽ phá vỡ, nhưng hầu như không tồn tại; từ quan điểm thực tế, đó không phải là vấn đề). Tôi có thể nghĩ ra một vài ngôn ngữ khác, HĐH (hoặc nhiều thứ khác liên quan đến máy tính) có thể đưa ra bất kỳ khiếu nại nào như vậy.

Sau đó, ông đi vào "phong cách luôn thay đổi". Một lần nữa, hầu hết các điểm của anh ấy khá gần với vô nghĩa. Anh ta cố gắng mô tả for (int i=0; i<n;i++) là "cũ và bị vỡ" và for (int i(0); i!=n;++i) "độ nóng mới". Thực tế là trong khi có những loại mà những thay đổi như vậy có thể có ý nghĩa, thì đối với int, nó không có gì khác biệt - và ngay cả khi bạn có thể đạt được điều gì đó, hiếm khi cần viết mã tốt hoặc đúng. Thậm chí là tốt nhất, anh ta đang tạo ra một ngọn núi từ một nốt ruồi.

Yêu cầu tiếp theo của ông là C++ đang "tối ưu hóa sai hướng" - cụ thể, trong khi ông thừa nhận rằng việc sử dụng các thư viện tốt là dễ dàng, ông tuyên bố rằng C++ "khiến việc viết thư viện tốt gần như không thể." Ở đây, tôi tin là một trong những sai lầm cơ bản nhất của anh ấy. Trong thực tế, viết thư viện tốt cho hầu hết bất kỳ ngôn ngữ là vô cùng khó khăn. Ở mức tối thiểu, viết một thư viện tốt đòi hỏi phải hiểu rõ một số miền có vấn đề để mã của bạn hoạt động cho vô số ứng dụng có thể có trong (hoặc liên quan đến) tên miền đó. Hầu hết những gì C++ thực sự thực hiện là "nâng cao thanh" - sau khi thấy thư viện tốt hơn bao nhiêu có thể, mọi người hiếm khi sẵn sàng quay lại viết các loại dreck họ sẽ có khác. Anh ta cũng bỏ qua thực tế là một vài thực sự lập trình viên giỏi viết khá nhiều thư viện, sau đó có thể được sử dụng (một cách dễ dàng, như anh ta thừa nhận) bởi "phần còn lại của chúng tôi". Đây thực sự là một trường hợp "đó không phải là một lỗi, đó là một tính năng."

Tôi sẽ không cố gắng đạt được mọi điểm theo thứ tự (sẽ mất các trang), nhưng bỏ qua trực tiếp đến điểm kết thúc của anh ấy. Ông trích dẫn Bjarne: "tối ưu hóa toàn bộ chương trình có thể được sử dụng để loại bỏ các bảng chức năng ảo và dữ liệu RTTI không sử dụng. Phân tích như vậy đặc biệt phù hợp với các chương trình tương đối nhỏ không sử dụng liên kết động."

Ông phê phán điều này bằng cách đưa ra một tuyên bố không được hỗ trợ rằng "Đây là một thực sự vấn đề khó khăn", thậm chí còn đi xa đến mức so sánh nó với vấn đề tạm dừng. Trên thực tế, không có gì thuộc loại này - trên thực tế, trình liên kết đi kèm với Zortech C++ (khá nhiều đầu tiên Trình biên dịch C++ cho MS-DOS, vào những năm 1980) đã làm điều này. Đúng là khó có thể chắc chắn rằng mọi bit dữ liệu ngoại lai có thể đã bị loại bỏ, nhưng vẫn hoàn toàn hợp lý để thực hiện một công việc khá công bằng.

Tuy nhiên, bất kể điều đó, điểm quan trọng hơn nhiều là điều này hoàn toàn không liên quan đến hầu hết các lập trình viên trong mọi trường hợp. Như những người trong chúng ta đã phân tách khá nhiều mã biết, trừ khi bạn viết ngôn ngữ hội không có thư viện nào cả, các tệp thực thi của bạn gần như chắc chắn chứa một lượng "nội dung" (cả mã và dữ liệu, trong trường hợp điển hình) mà bạn thậm chí có thể không biết về, không đề cập đến bao giờ thực sự sử dụng. Đối với hầu hết mọi người, hầu hết thời gian, điều đó không thành vấn đề - trừ khi bạn đang phát triển cho các hệ thống nhúng nhỏ nhất, việc tiêu thụ thêm dung lượng chỉ đơn giản là không liên quan.

Cuối cùng, sự thật là lời tán dương này có một chút chất hơn so với sự ngốc nghếch của Linus - nhưng điều đó mang lại cho nó chính xác sự đáng nguyền rủa với lời khen ngợi mờ nhạt mà nó xứng đáng.

2
Jerry Coffin

Là một lập trình viên C đã phải viết mã trong C++ do hoàn cảnh không thể tránh khỏi, đây là kinh nghiệm của tôi. Có rất ít thứ tôi sử dụng đó là C++ và chủ yếu dính vào C. Lý do chính là vì tôi không hiểu rõ về C++. Tôi đã/không có một người cố vấn để chỉ cho tôi thấy sự phức tạp của C++ và cách viết mã tốt trong đó. Và không có hướng dẫn từ một mã C++ rất tốt, việc viết mã tốt trong C++ là cực kỳ khó khăn. IMHO đây là nhược điểm lớn nhất của C++ vì các lập trình viên C++ giỏi sẵn sàng nắm bắt những người mới bắt đầu rất khó để có được.

Một số lượt truy cập hiệu suất mà tôi đã thấy thường là do phân bổ bộ nhớ ma thuật của STL (vâng, bạn có thể thay đổi bộ cấp phát, nhưng ai làm điều đó khi anh ấy bắt đầu với C++?). Bạn thường nghe các lập luận của các chuyên gia C++ rằng các vectơ và mảng cung cấp hiệu suất tương tự, vì các vectơ sử dụng các mảng bên trong và sự trừu tượng là siêu hiệu quả. Tôi đã thấy điều này là đúng trong thực tế đối với truy cập véc tơ và sửa đổi các giá trị hiện có. Nhưng không đúng khi thêm một mục mới, xây dựng và phá hủy các vectơ. gprof đã chỉ ra rằng 25% thời gian tích lũy cho một ứng dụng được dành cho các hàm tạo vector, hàm hủy, memmove (để di chuyển toàn bộ vector để thêm phần tử mới) và các toán tử vector quá tải khác (như ++).

Trong cùng một ứng dụng, vectơ của SomethingSmall đã được sử dụng để thể hiện một cái gì đóBig. Không cần truy cập ngẫu nhiên một cái gì đó nhỏ trong một cái gì đóBig. Vẫn còn một vector được sử dụng thay vì một danh sách. Lý do tại sao vector được sử dụng? Bởi vì bộ mã hóa ban đầu đã quen thuộc với mảng như cú pháp của vectơ và không quen thuộc với các trình vòng lặp cần thiết cho các danh sách (vâng, anh ta đến từ nền C). Tiếp tục chứng minh rằng cần có nhiều hướng dẫn từ các chuyên gia để có được C++ ngay. C cung cấp rất ít các cấu trúc cơ bản mà hoàn toàn không có sự trừu tượng hóa, do đó bạn có thể làm cho nó dễ dàng hơn nhiều so với C++.

1
aufather

Mặc dù tôi thích Linus Thorvalds, nhưng lời nói này không có chất - chỉ là một lời nói.

Nếu bạn muốn thấy một lời tán dương, đây là một câu: "Tại sao C++ lại có hại cho môi trường, gây ra sự nóng lên toàn cầu và giết chết những chú chó con" http://chaosradio.ccc.de/camp2007_m4v_1951.html Bổ sung tài liệu: http://www.fefe.de/c++/

Một cuộc nói chuyện thú vị, imho

0
user unknown

STL và boost là xách tay, ở cấp mã nguồn. Tôi đoán những gì Linus đang nói là C++ thiếu ABI (giao diện nhị phân ứng dụng). Vì vậy, bạn cần phải biên dịch tất cả các thư viện mà bạn liên kết, với cùng một phiên bản trình biên dịch và với cùng các công tắc, hoặc nếu không thì giới hạn bản thân bạn trong C ABI tại các biên giới dll. Tôi cũng thấy rằng đang hoạt động .. nhưng trừ khi bạn đang tạo thư viện bên thứ 3, bạn sẽ có thể kiểm soát môi trường xây dựng của mình. Tôi thấy việc giới hạn bản thân mình vào C ABI không đáng để gặp rắc rối. Sự tiện lợi của việc có thể truyền chuỗi, vectơ và con trỏ thông minh từ dll này sang dll khác là vấn đề đáng ngại khi phải xây dựng lại tất cả các thư viện khi nâng cấp trình biên dịch hoặc thay đổi chuyển đổi trình biên dịch. Các nguyên tắc vàng tôi tuân theo là:

-Inhitit để sử dụng lại giao diện, không thực hiện

Tổng hợp -Prefer hơn thừa kế

-Prefer nơi các chức năng miễn phí có thể cho các phương thức thành viên

-Luôn sử dụng thành ngữ RAII để làm cho mã của bạn ngoại lệ mạnh mẽ an toàn. Tránh thử bắt.

-Sử dụng con trỏ thông minh, tránh con trỏ trần (không có chủ)

-Prefer giá trị ngữ nghĩa để tham khảo ngữ nghĩa

-Không phát minh lại bánh xe, sử dụng stl và boost

-Sử dụng thành ngữ Pimpl để ẩn riêng tư và/hoặc để cung cấp tường lửa trình biên dịch

0
user16642