Có phải là một cách thực hành tốt để đặt các định nghĩa C ++ trong các tệp tiêu đề?


196

Phong cách cá nhân của tôi với C ++ luôn đặt các khai báo lớp trong một tệp bao gồm và các định nghĩa trong tệp .cpp, rất giống như quy định trong câu trả lời của Loki đối với các tệp tiêu đề C ++, Tách mã . Phải thừa nhận rằng, một phần lý do tôi thích phong cách này có lẽ phải làm với tất cả những năm tôi đã sử dụng mã hóa Modula-2 và Ada, cả hai đều có sơ đồ tương tự với các tệp đặc tả và tệp cơ thể.

Tôi có một đồng nghiệp, hiểu biết nhiều về C ++ hơn tôi, người luôn khăng khăng rằng tất cả các khai báo C ++ nên, nếu có thể, bao gồm các định nghĩa ngay trong tệp tiêu đề. Anh ấy không nói rằng đây là một phong cách thay thế hợp lệ, hoặc thậm chí là một phong cách tốt hơn một chút, nhưng đây là phong cách mới được chấp nhận phổ biến mà mọi người hiện đang sử dụng cho C ++.

Tôi không khập khiễng như trước đây, vì vậy tôi không thực sự lo lắng khi trèo lên băng đảng này cho đến khi tôi gặp thêm một vài người ở đó với anh ta. Vì vậy, làm thế nào phổ biến là thành ngữ này thực sự?

Chỉ cần đưa ra một số cấu trúc cho các câu trả lời: Có phải bây giờ là The Way , rất phổ biến, hơi phổ biến, không phổ biến hoặc lỗi điên?


các hàm một dòng (getters và setters) trong tiêu đề là phổ biến. Lâu hơn sẽ có được một cái nhìn thứ hai đố vui. Có lẽ đối với định nghĩa đầy đủ của một lớp nhỏ chỉ được sử dụng bởi một lớp khác trong cùng một tiêu đề?
Martin Beckett

tôi đã luôn luôn đặt tất cả các định nghĩa lớp học của tôi trong các tiêu đề cho đến nay. chỉ định nghĩa cho các lớp pimpl là ngoại lệ. tôi chỉ tuyên bố những người trong tiêu đề.
Julian Schaub - litb

3
Có lẽ anh ấy nghĩ rằng đó là cách vì Visual C ++ khẳng định rằng mã được viết. Khi bạn bấm vào một nút, việc thực hiện được tạo ra trong tệp tiêu đề. Tôi không biết tại sao Microsoft lại khuyến khích điều này mặc dù vì những lý do mà những người khác đã giải thích dưới đây.
WKS

4
@WKS - Microsoft muốn mọi người lập trình trong C # và trong C #, không có sự phân biệt "tiêu đề" và "cơ thể", đó chỉ là một tệp. Đã ở trong cả hai thế giới C ++ và C # từ lâu, cách thức C # thực sự dễ đối phó hơn nhiều.
Mark Lakata

1
@MarkLakata - Đó thực sự là một trong những điều anh ấy chỉ ra. Gần đây tôi không nghe thấy lập luận này về anh ta, nhưng IIRC anh ta đã lập luận rằng Java và C # hoạt động theo cách này và C # hoàn toàn mới vào thời điểm đó, điều này khiến nó trở thành xu hướng tất cả các ngôn ngữ sẽ sớm theo sau
TED

Câu trả lời:


209

Đồng nghiệp của bạn đã sai, cách phổ biến là và luôn luôn đặt mã trong các tệp .cpp (hoặc bất kỳ tiện ích mở rộng nào bạn muốn) và khai báo trong các tiêu đề.

Thỉnh thoảng có một số công đức để đặt mã trong tiêu đề, điều này có thể cho phép trình biên dịch thông minh hơn. Nhưng đồng thời, nó có thể phá hủy thời gian biên dịch của bạn vì tất cả mã phải được xử lý mỗi khi nó được trình biên dịch đưa vào.

Cuối cùng, thường rất khó chịu khi có các mối quan hệ đối tượng tròn (đôi khi mong muốn) khi tất cả các mã là các tiêu đề.

Tóm lại, bạn đã đúng, anh sai.

EDIT: Tôi đã suy nghĩ về câu hỏi của bạn. Có một trường hợp mà những gì anh ấy nói là đúng. mẫu. Nhiều thư viện "hiện đại" mới hơn như boost sử dụng rất nhiều mẫu và thường chỉ là "tiêu đề". Tuy nhiên, điều này chỉ nên được thực hiện khi xử lý các mẫu vì đó là cách duy nhất để làm điều đó khi giao dịch với chúng.

EDIT: Một số người muốn làm rõ hơn một chút, đây là một số suy nghĩ về nhược điểm để viết mã "chỉ tiêu đề":

Nếu bạn tìm kiếm xung quanh, bạn sẽ thấy khá nhiều người đang cố gắng tìm cách giảm thời gian biên dịch khi xử lý boost. Ví dụ: Cách giảm thời gian biên dịch với Boost Asio , đang xem phần biên dịch 14 giây của một tệp 1K có kèm theo boost. Số 14 có vẻ không "bùng nổ", nhưng chắc chắn nó dài hơn rất nhiều so với thông thường và có thể tăng lên khá nhanh. Khi giao dịch với một dự án lớn. Các thư viện chỉ tiêu đề không ảnh hưởng đến thời gian biên dịch theo cách khá đo lường được. Chúng tôi chỉ chịu đựng nó vì boost rất hữu ích.

Ngoài ra, có nhiều thứ không thể được thực hiện chỉ trong các tiêu đề (thậm chí boost có các thư viện bạn cần liên kết đến một số phần nhất định như luồng, hệ thống tệp, v.v.). Một ví dụ chính là bạn không thể có các đối tượng toàn cầu đơn giản trong libs tiêu đề (trừ khi bạn sử dụng từ gớm ghiếc là một singleton) vì bạn sẽ gặp phải nhiều lỗi định nghĩa. LƯU Ý: Các biến nội tuyến của C ++ 17 sẽ làm cho ví dụ cụ thể này có thể thực hiện được trong tương lai.

Như một điểm cuối cùng, khi sử dụng boost làm ví dụ về mã chỉ tiêu đề, một chi tiết lớn thường bị bỏ qua.

Boost là thư viện, không phải mã cấp độ người dùng. vì vậy nó không thay đổi thường xuyên. Trong mã người dùng, nếu bạn đặt mọi thứ vào tiêu đề, mỗi thay đổi nhỏ sẽ khiến bạn phải biên dịch lại toàn bộ dự án. Đó là một sự lãng phí thời gian lớn (và không phải là trường hợp đối với các thư viện không thay đổi từ biên dịch sang biên dịch). Khi bạn phân chia mọi thứ giữa tiêu đề / nguồn và tốt hơn nữa, hãy sử dụng khai báo chuyển tiếp để giảm bao gồm, bạn có thể tiết kiệm hàng giờ biên dịch lại khi được thêm vào trong một ngày.


16
Tôi khá chắc chắn rằng đó là nơi anh ấy nhận được nó. Khi điều này xuất hiện, ông đưa ra các mẫu. Lập luận của ông đại khái là bạn nên làm tất cả mã theo cách này để thống nhất.
TED

14
đó là một cuộc tranh luận tồi tệ mà anh ta đưa ra, hãy bám lấy súng của bạn :)
Evan Teran

11
Định nghĩa mẫu có thể có trong các tệp CPP nếu từ khóa "xuất" được hỗ trợ. Đó là một góc tối của C ++ thường không được hầu hết các trình biên dịch triển khai, theo sự hiểu biết tốt nhất của tôi.
Andrei Taranchenko

2
Xem phần dưới của câu trả lời này (phần trên có phần phức tạp) để biết ví dụ: stackoverflow.com/questions/555330/ Kẻ
Evan Teran

3
Nó bắt đầu có ý nghĩa với cuộc thảo luận này tại "Hoan hô, không có lỗi liên kết."
Evan Teran

157

Ngày các lập trình viên C ++ đồng ý trên The Way , những con cừu sẽ nằm xuống với sư tử, người Palestine sẽ ôm lấy người Israel và mèo và chó sẽ được phép kết hôn.

Sự tách biệt giữa các tệp .h và .cpp chủ yếu là tùy ý tại thời điểm này, một dấu tích của tối ưu hóa trình biên dịch trong quá khứ. Trước mắt tôi, các khai báo thuộc về tiêu đề và các định nghĩa thuộc về tệp thực thi. Nhưng, đó chỉ là thói quen, không phải tôn giáo.


140
"Ngày mà các lập trình viên C ++ đồng ý trên The Way ..." sẽ chỉ còn một lập trình viên C ++!
Brian Consink

9
Tôi nghĩ rằng họ đã đồng ý trên đường đi, khai báo trong .h và định nghĩa trong .cpp
hasen

6
Chúng ta đều là những người mù và C ++ là một con voi.
Roderick Taylor

thói quen? Vậy còn việc sử dụng .h để xác định phạm vi thì sao? bởi cái gì nó đã được thay thế?
Hernán Eche

28

Mã trong các tiêu đề nói chung là một ý tưởng tồi vì nó buộc biên dịch lại tất cả các tệp bao gồm tiêu đề khi bạn thay đổi mã thực tế thay vì khai báo. Nó cũng sẽ làm chậm quá trình biên dịch vì bạn sẽ cần phân tích mã trong mỗi tệp bao gồm tiêu đề.

Một lý do để có mã trong các tệp tiêu đề là vì thông thường cần cho từ khóa nội tuyến hoạt động chính xác và khi sử dụng các mẫu đang được kích hoạt trong các tệp cpp khác.


1
"Nó buộc biên dịch lại tất cả các tệp bao gồm tiêu đề khi bạn thay đổi mã thực tế thay vì khai báo" Tôi nghĩ đây là lý do chính đáng nhất; cũng đi với thực tế là các khai báo trong các tiêu đề thay đổi ít thường xuyên hơn so với việc thực hiện trong các tệp .c.
Ninad

20

Những gì có thể thông báo cho bạn đồng nghiệp là một khái niệm rằng hầu hết mã C ++ nên được tạo khuôn mẫu để cho phép khả năng sử dụng tối đa. Và nếu nó được tạo khuôn mẫu, thì mọi thứ sẽ cần phải nằm trong một tệp tiêu đề, để mã máy khách có thể nhìn thấy nó và khởi tạo nó. Nếu nó đủ tốt cho Boost và STL, thì nó đủ tốt cho chúng tôi.

Tôi không đồng ý với quan điểm này, nhưng nó có thể đến từ đâu.


Tôi nghĩ bạn đúng về điều này. Khi chúng tôi thảo luận về nó, anh ấy luôn sử dụng ví dụ về các mẫu, nơi bạn ít nhiều phải làm điều này. Tôi cũng không đồng ý với "phải", nhưng các lựa chọn thay thế của tôi khá phức tạp.
TED

1
@ted - đối với mã templated, bạn cần phải thực hiện trong tiêu đề. Từ khóa 'xuất khẩu' cho phép trình biên dịch hỗ trợ phân tách khai báo và định nghĩa mẫu, nhưng hỗ trợ xuất khẩu là không tồn tại. anubis.dkuug.dk/jtc1/sc22/wg21/docs/ con / 2003 / n1426.pdf
Michael Burr

Một tiêu đề, có, nhưng nó không phải là cùng một tiêu đề. Xem câu trả lời chưa biết dưới đây.
TED

Điều đó có ý nghĩa, nhưng tôi không thể nói rằng tôi đã bắt gặp phong cách đó trước đây.
Michael Burr

14

Tôi nghĩ rằng đồng nghiệp của bạn thông minh và bạn cũng đúng.

Những điều hữu ích tôi thấy rằng đặt mọi thứ vào tiêu đề là:

  1. Không cần phải viết & tiêu đề đồng bộ hóa và nguồn.

  2. Cấu trúc đơn giản và không phụ thuộc vòng tròn buộc người viết mã phải tạo ra cấu trúc "tốt hơn".

  3. Di động, dễ dàng để nhúng vào một dự án mới.

Tôi đồng ý với vấn đề biên dịch thời gian, nhưng tôi nghĩ chúng ta nên chú ý rằng:

  1. Việc thay đổi tệp nguồn rất có khả năng thay đổi các tệp tiêu đề dẫn đến toàn bộ dự án được biên dịch lại.

  2. Tốc độ biên dịch nhanh hơn nhiều so với trước đây. Và nếu bạn có một dự án được xây dựng với thời gian dài và tần suất cao, nó có thể chỉ ra rằng thiết kế dự án của bạn có sai sót. Phân chia các nhiệm vụ vào các dự án và mô-đun khác nhau có thể tránh được vấn đề này.

Cuối cùng tôi chỉ muốn hỗ trợ đồng nghiệp của bạn, theo quan điểm cá nhân của tôi.


3
+1. Không ai ngoài bạn có ý tưởng rằng trong một tiêu đề chỉ dự án thời gian biên dịch dài có thể gợi ý cho quá nhiều phụ thuộc vốn là thiết kế xấu. Điểm tốt! Nhưng những phụ thuộc này có thể được loại bỏ đến một mức độ mà thời gian biên dịch thực sự ngắn không?
TobiMcNamobi

@TobiMcNamobi: Tôi thích ý tưởng "chần chừ" để nhận phản hồi tốt hơn về các quyết định thiết kế tồi. Tuy nhiên, trong trường hợp chỉ có tiêu đề so với biên dịch riêng, nếu chúng tôi giải quyết được ý tưởng đó, chúng tôi sẽ kết thúc với một đơn vị biên dịch duy nhất và thời gian biên dịch lớn. Ngay cả khi thiết kế thực sự tuyệt vời.
Jo So

Nói cách khác, sự tách biệt giữa giao diện và triển khai thực sự là một phần trong thiết kế của bạn. Trong C, bạn được yêu cầu thể hiện quyết định của mình về đóng gói thông qua phân tách trong tiêu đề và thực hiện.
Jo So

1
Tôi bắt đầu tự hỏi liệu có bất kỳ nhược điểm nào không chỉ là bỏ tiêu đề hoàn toàn giống như các ngôn ngữ hiện đại.
Jo So

12

Thông thường tôi sẽ đặt các hàm thành viên tầm thường vào tệp tiêu đề để cho phép chúng được nội tuyến. Nhưng để đặt toàn bộ cơ thể của mã ở đó, chỉ để phù hợp với các mẫu? Đó là các loại hạt đơn giản.

Hãy nhớ rằng: Một sự nhất quán ngu ngốc là hobgoblin của những bộ óc nhỏ .


Vâng, tôi cũng làm điều đó. Quy tắc chung mà tôi sử dụng dường như là một cái gì đó dọc theo dòng "nếu nó phù hợp với một dòng mã, hãy để nó trong tiêu đề".
TED

Điều gì xảy ra khi một thư viện cung cấp phần thân của một lớp mẫu A<B>trong tệp cpp, và sau đó người dùng muốn một A<C>?
jww

@jww Tôi không nói rõ ràng, nhưng các lớp mẫu nên được xác định đầy đủ trong các tiêu đề để trình biên dịch có thể khởi tạo nó với bất kỳ loại nào nó cần. Đó là một yêu cầu kỹ thuật, không phải là một sự lựa chọn phong cách. Tôi nghĩ vấn đề trong câu hỏi ban đầu là ai đó đã quyết định nếu nó tốt cho các mẫu, nó cũng tốt cho các lớp thông thường.
Đánh dấu tiền chuộc

7

Như Tuomas đã nói, tiêu đề của bạn nên tối thiểu. Để được hoàn thành tôi sẽ mở rộng một chút.

Cá nhân tôi sử dụng 4 loại tệp trong C++các dự án của mình :

  • Công cộng:
  • Tiêu đề chuyển tiếp: trong trường hợp mẫu v.v., tệp này nhận được các khai báo chuyển tiếp sẽ xuất hiện trong tiêu đề.
  • Tiêu đề: tệp này bao gồm tiêu đề chuyển tiếp, nếu có và khai báo mọi thứ tôi muốn công khai (và xác định các lớp ...)
  • Riêng tư:
  • Tiêu đề riêng: tệp này là một tiêu đề dành riêng để thực hiện, nó bao gồm tiêu đề và khai báo các chức năng / cấu trúc của trình trợ giúp (ví dụ như Pimpl hoặc các vị từ). Bỏ qua nếu không cần thiết.
  • Tệp nguồn: nó bao gồm tiêu đề riêng (hoặc tiêu đề nếu không có tiêu đề riêng) và xác định mọi thứ (không phải mẫu ...)

Hơn nữa, tôi kết hợp điều này với một quy tắc khác: Không xác định những gì bạn có thể chuyển tiếp khai báo. Mặc dù tất nhiên tôi hợp lý ở đó (sử dụng Pimpl ở mọi nơi khá rắc rối).

Điều đó có nghĩa là tôi thích một tuyên bố chuyển tiếp hơn một #includechỉ thị trong các tiêu đề của tôi bất cứ khi nào tôi có thể tránh xa chúng.

Cuối cùng, tôi cũng sử dụng quy tắc hiển thị: Tôi giới hạn phạm vi biểu tượng của mình càng nhiều càng tốt để chúng không làm ô nhiễm phạm vi bên ngoài.

Đặt nó hoàn toàn:

// example_fwd.hpp
// Here necessary to forward declare the template class,
// you don't want people to declare them in case you wish to add
// another template symbol (with a default) later on
class MyClass;
template <class T> class MyClassT;

// example.hpp
#include "project/example_fwd.hpp"

// Those can't really be skipped
#include <string>
#include <vector>

#include "project/pimpl.hpp"

// Those can be forward declared easily
#include "project/foo_fwd.hpp"

namespace project { class Bar; }

namespace project
{
  class MyClass
  {
  public:
    struct Color // Limiting scope of enum
    {
      enum type { Red, Orange, Green };
    };
    typedef Color::type Color_t;

  public:
    MyClass(); // because of pimpl, I need to define the constructor

  private:
    struct Impl;
    pimpl<Impl> mImpl; // I won't describe pimpl here :p
  };

  template <class T> class MyClassT: public MyClass {};
} // namespace project

// example_impl.hpp (not visible to clients)
#include "project/example.hpp"
#include "project/bar.hpp"

template <class T> void check(MyClass<T> const& c) { }

// example.cpp
#include "example_impl.hpp"

// MyClass definition

Nhân viên cứu hộ ở đây là hầu hết các lần tiêu đề chuyển tiếp là vô ích: chỉ cần thiết trong trường hợp typedefhoặc templatetiêu đề thực hiện cũng vậy;)


6

Để thêm phần thú vị, bạn có thể thêm .ippcác tệp chứa triển khai mẫu (đang được đưa vào .hpp), trong khi .hppcó giao diện.

Ngoài mã templatized (tùy thuộc vào dự án, đây có thể là đa số hoặc thiểu số tệp), có mã bình thường và ở đây tốt hơn là tách các khai báo và định nghĩa. Cung cấp cả khai báo chuyển tiếp khi cần - điều này có thể có ảnh hưởng đến thời gian biên dịch.


Đó cũng là những gì tôi đã làm với các định nghĩa mẫu (mặc dù tôi không chắc là tôi đã sử dụng cùng một tiện ích mở rộng ... đã được một lúc rồi).
TED

5

Nói chung, khi viết một lớp mới, tôi sẽ đặt tất cả mã vào lớp, vì vậy tôi không phải tìm một tệp khác cho nó .. Sau khi mọi thứ đang hoạt động, tôi chia phần thân của các phương thức thành tệp cpp , để lại các nguyên mẫu trong tệp hpp.


4

Nếu cách mới này thực sự là Con đường , chúng ta có thể đã chạy theo hướng khác trong các dự án của mình.

Bởi vì chúng tôi cố gắng tránh tất cả những thứ không cần thiết trong tiêu đề. Điều đó bao gồm tránh thác tiêu đề. Mã trong các tiêu đề sẽ có thể cần một số tiêu đề khác được đưa vào, sẽ cần một tiêu đề khác, v.v. Nếu chúng tôi buộc phải sử dụng các mẫu, chúng tôi cố gắng tránh các tiêu đề xả rác với các công cụ mẫu quá nhiều.

Ngoài ra, chúng tôi sử dụng "con trỏ mờ" khi áp dụng.

Với những thực hành này, chúng tôi có thể thực hiện các bản dựng nhanh hơn hầu hết các đồng nghiệp của chúng tôi. Và vâng ... thay đổi mã hoặc các thành viên lớp sẽ không gây ra việc xây dựng lại lớn.


4

Cá nhân tôi làm điều này trong các tập tin tiêu đề của tôi:

// class-declaration

// inline-method-declarations

Tôi không thích trộn mã cho các phương thức trong lớp vì tôi thấy thật khó khăn để tìm kiếm mọi thứ một cách nhanh chóng.

Tôi sẽ không đặt TẤT CẢ các phương thức trong tệp tiêu đề. Trình biên dịch sẽ (thông thường) không thể định tuyến các phương thức ảo và sẽ (có thể) chỉ các phương thức nhỏ nội tuyến không có vòng lặp (hoàn toàn phụ thuộc vào trình biên dịch).

Thực hiện các phương thức trong lớp là hợp lệ ... nhưng từ quan điểm có thể đọc được, tôi không thích nó. Đặt các phương thức trong tiêu đề có nghĩa là, khi có thể, chúng sẽ được nội tuyến.


2

IMHO, anh ấy chỉ có công nếu anh ấy làm mẫu và / hoặc siêu lập trình. Có rất nhiều lý do đã được đề cập rằng bạn giới hạn các tệp tiêu đề chỉ là khai báo. Họ chỉ là ... tiêu đề. Nếu bạn muốn bao gồm mã, bạn biên dịch nó dưới dạng thư viện và liên kết nó lên.


2

Tôi đặt tất cả các thực hiện ra khỏi định nghĩa lớp. Tôi muốn có các bình luận doxygen ra khỏi định nghĩa lớp.


1
Tôi biết đó là muộn, nhưng downvoters (hoặc đồng cảm) quan tâm để bình luận tại sao? Đây dường như là một tuyên bố hợp lý với tôi. Chúng tôi sử dụng Doxygen, và vấn đề chắc chắn đã đưa ra.
TED

2

Tôi nghĩ rằng việc đặt TẤT CẢ các định nghĩa hàm của bạn vào tệp tiêu đề là hoàn toàn vô lý. Tại sao? Bởi vì tệp tiêu đề được sử dụng làm giao diện PUBLIC cho lớp của bạn. Đó là bên ngoài của "hộp đen".

Khi bạn cần xem một lớp để tham khảo cách sử dụng nó, bạn nên xem tệp tiêu đề. Tệp tiêu đề sẽ đưa ra một danh sách những gì nó có thể làm (được nhận xét để mô tả chi tiết về cách sử dụng từng chức năng) và nó sẽ bao gồm một danh sách các biến thành viên. Nó KHÔNG NÊN bao gồm CÁCH mỗi chức năng riêng lẻ được triển khai, bởi vì đó là một khối lượng thông tin không cần thiết và chỉ làm xáo trộn tệp tiêu đề.


1

Điều đó có thực sự phụ thuộc vào sự phức tạp của hệ thống và các quy ước nội bộ không?

Hiện tại tôi đang làm việc trên một trình giả lập mạng thần kinh cực kỳ phức tạp và phong cách được chấp nhận mà tôi dự kiến ​​sẽ sử dụng là:

Các định nghĩa lớp trong classname.h
Mã lớp trong classnameCode.h
mã thực thi trong classname.cpp

Điều này phân tách các mô phỏng do người dùng xây dựng từ các lớp cơ sở do nhà phát triển xây dựng và hoạt động tốt nhất trong tình huống.

Tuy nhiên, tôi rất ngạc nhiên khi thấy mọi người thực hiện điều này trong một ứng dụng đồ họa hoặc bất kỳ ứng dụng nào khác nhằm mục đích không cung cấp cho người dùng cơ sở mã.


1
Chính xác thì sự khác biệt giữa "Mã lớp" và "Mã thực thi" là gì?
TED

Như tôi đã nói, đó là một trình giả lập thần kinh: Người dùng tạo các mô phỏng thực thi được xây dựng trên một số lượng lớn các lớp hoạt động như các nơ-ron, v.v. Điều đó làm cho trình giả lập làm công cụ.
Ed James

Nói chung, bạn không thể nói "thực sự không thể tự làm bất cứ điều gì" cho đại đa số (nếu không phải là toàn bộ) của hầu hết các chương trình? Bạn đang nói rằng mã "chính" đi trong một cpp, nhưng không có gì khác?
TED

Trong tình huống này, nó hơi khác một chút. Mã mà chúng tôi viết về cơ bản là một thư viện và người dùng xây dựng các mô phỏng của họ trên đầu trang này, thực sự có thể chạy được. Hãy suy nghĩ về nó như openGL -> bạn có được một loạt các chức năng và đối tượng nhưng không có tệp cpp có thể chạy chúng thì chúng vô dụng.
Ed James

0

Mã mẫu chỉ nên ở tiêu đề. Ngoài ra, tất cả các định nghĩa ngoại trừ nội tuyến nên có trong .cpp. Đối số tốt nhất cho điều này sẽ là các triển khai thư viện tiêu chuẩn theo cùng một quy tắc. Bạn sẽ không đồng ý các nhà phát triển lib std sẽ đúng về vấn đề này.


Những stdlibs? libstdc++Dường như (AFAICS) của GCC gần như không đặt gì vào src& hầu hết mọi thứ trong đó include, dù nó 'phải' nằm trong một tiêu đề. Vì vậy, tôi không nghĩ rằng đây là một trích dẫn chính xác / hữu ích. Dù sao, tôi không nghĩ stdlibs là một mô hình cho mã người dùng: rõ ràng chúng được viết bởi các lập trình viên có tay nghề cao, nhưng được sử dụng , không được đọc: chúng trừu tượng hóa sự phức tạp cao mà hầu hết các lập trình viên không cần phải suy nghĩ , cần xấu xí _Reserved __namesở mọi nơi để tránh xung đột với người dùng, các bình luận và khoảng cách đều nằm dưới những gì tôi khuyên, v.v ... Họ mẫu mực theo một cách hẹp.
gạch dưới

0

Tôi nghĩ rằng đồng nghiệp của bạn là đúng miễn là anh ta không tham gia vào quá trình để viết mã thực thi trong tiêu đề. Theo tôi, sự cân bằng phù hợp là đi theo đường dẫn được chỉ định bởi GNAT Ada trong đó tệp .ads đưa ra định nghĩa giao diện hoàn toàn đầy đủ của gói cho người dùng và cho con của nó.

Nhân tiện, Ted, bạn đã xem diễn đàn này cho câu hỏi gần đây về Ada liên kết với thư viện CLIPS mà bạn đã viết cách đây vài năm và không còn nữa (các trang Web có liên quan hiện đang đóng). Ngay cả khi được tạo thành phiên bản Clip cũ, ràng buộc này có thể là một ví dụ khởi đầu tốt cho ai đó sẵn sàng sử dụng công cụ suy luận CLIPS trong chương trình Ada 2012.


1
Cười lớn. 2 năm sau, đây là một cách kỳ lạ để giữ lấy một ai đó. Tôi sẽ kiểm tra nếu tôi vẫn còn một bản sao, nhưng rất có thể là không. Tôi đã làm điều đó cho một lớp AI để tôi có thể thực hiện mã của mình trong Ada, nhưng đã cố tình thực hiện dự án Muff (về cơ bản là không bị che chở) với hy vọng ai đó sẽ biết xấu hổ lấy nó và làm gì đó với nó.
TED
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.