Nếu bạn khai báo getters/setters của lớp bên trong tệp .h và sau đó xác định chúng trong .cpp Hoặc làm cả hai trong tệp .h. Bạn thích kiểu nào hơn và tại sao? Cá nhân tôi thích thứ hai trong đó tất cả chúng đều nằm trong .h và chỉ có các phương thức có logic liên kết với nó ngoài các bộ định cư/getters trong .cpp.Kiểu lập trình khai báo phương thức của các biến phương thức get/set trong C++?
Trả lời
Đối với tôi, tùy thuộc vào người sẽ sử dụng tệp .h. Nếu đó là một tập tin phần lớn nội bộ cho một mô-đun, sau đó tôi có xu hướng đặt các phương pháp nhỏ trong tiêu đề. Nếu đó là một tệp tiêu đề bên ngoài nhiều hơn trình bày một API cố định hơn, thì tôi sẽ đặt mọi thứ trong tệp .cpp. Trong trường hợp này, tôi thường sử dụng PIMPL Idiom để có tường lửa biên dịch đầy đủ.
The trade-offs tôi thấy với cách đặt chúng trong các tiêu đề là:
- Ít gõ nội tuyến
- dễ dàng hơn cho các trình biên dịch (mặc dù trình biên dịch đôi khi có thể làm nội tuyến giữa nhiều đơn vị dịch bây giờ anyway.)
- Các phụ thuộc biên dịch khác
Tôi muốn nói rằng tệp tiêu đề phải là về giao diện chứ không phải triển khai. Tôi đặt chúng trong .cpp.
Tôi luôn theo dõi sự phân chia khai báo chúng trong tiêu đề và xác định trong nguồn. Mỗi khi tôi không làm vậy, cuối cùng tôi phải quay lại và làm theo bất cứ cách nào sau này.
Tôi đặt tất cả các lớp lót đơn trong tiêu đề miễn là chúng không yêu cầu quá nhiều tiêu đề bổ sung đi kèm (vì phương thức gọi của các lớp khác). Ngoài ra tôi không cố gắng để đặt tất cả các mã trong một dòng vì vậy tôi có thể đặt hầu hết các phương pháp trong tiêu đề :-)
Nhưng Josh đã đề cập một lý do chính đáng để đặt chúng trong .cpp anyway: nếu tiêu đề là dùng ngoài da.
Tôi thích đặt chúng vào tệp .cpp, vì lợi ích của thời gian biên dịch/liên kết nhanh. Ngay cả một nhỏ lót (trống ảo destructors!) Có thể thổi lên thời gian biên dịch của bạn, nếu chúng được instantiated rất nhiều. Trong một dự án, tôi có thể cắt thời gian biên dịch bằng một vài giây bằng cách di chuyển tất cả các destructor ảo vào các tệp .cpp.
Kể từ đó, tôi được bán trên này, và tôi sẽ chỉ đưa chúng vào tiêu đề một lần nữa nếu một profiler nói với tôi rằng tôi có thể lợi nhuận từ nội tuyến. Nhược điểm duy nhất là bạn cần gõ nhiều hơn, nhưng nếu bạn tạo tệp .cpp trong khi bạn viết tiêu đề, bạn thường có thể sao chép & dán các khai báo và điền chúng vào tệp .cpp, vì vậy nó không phải là xấu. Tồi tệ hơn tất nhiên nếu sau này bạn phát hiện ra bạn muốn chuyển nội dung vào tệp .cpp.
Một hiệu ứng phụ tốt đẹp là công cụ đọc đơn giản hơn khi bạn chỉ có tài liệu và khai báo trong tiêu đề của mình, đặc biệt nếu các nhà phát triển mới tham gia dự án.
Tôi sử dụng quy tắc tiếp theo: tiêu đề để khai báo, tệp mã để thực hiện. Nó sẽ trở thành thực tế khi tiêu đề của bạn sẽ được sử dụng bên ngoài dự án - hơn tiêu đề nhẹ của bạn, sau đó thoải mái hơn khi sử dụng
Tôi muốn giữ tệp .h càng sạch càng tốt. Do đó, các hàm nhỏ đơn giản như get/set tôi thường sử dụng để đưa vào một tệp riêng biệt như các hàm được định nghĩa nội tuyến, và sau đó bao gồm tệp đó (nơi tôi sử dụng phần mở rộng .inl) vào.h tập tin tiêu đề:
// foo.h
class foo
{
public:
int bar() const;
private:
int m_bar;
};
#include "foo.inl"
// foo.inl
inline
int foo::bar() const
{
return m_bar;
}
Tôi nghĩ rằng điều này sẽ cho là tốt nhất của hai thế giới, đồng thời ẩn nhất của việc thực hiện từ tiêu đề, và vẫn giữ lợi thế của nội tuyến mã đơn giản (như là một quy luật của Tôi giữ nó trong tối đa 3 câu).
Đối với tôi điều này phụ thuộc vào những gì tôi đang làm với mã. Đối với mã mà tôi muốn duy trì và kéo dài theo thời gian, tôi đặt tất cả mọi thứ trong tệp .cc vì các lý do sau:
- Tệp .h có thể giữ nguyên làm tài liệu cho những người muốn tìm hàm và phương pháp các định nghĩa.
- Nguyên tắc mã hóa của nhóm của tôi nêu rõ rằng chúng tôi đặt mọi thứ vào tệp .cpp và muốn theo dõi chúng, ngay cả khi định nghĩa hàm chỉ mất một dòng. Điều này giúp loại bỏ các trò chơi đoán về những nơi thực sự sống, bởi vì bạn biết bạn nên kiểm tra tập tin nào.
- Nếu bạn thường xuyên biên tập lại dự án lớn, hãy giữ định nghĩa hàm trong tệp .cpp giúp bạn tiết kiệm thời gian so với việc giữ các định nghĩa hàm trong tệp tiêu đề. Điều này có liên quan rất gần đây đối với chúng tôi, vì gần đây chúng tôi đã xem xét mã và bổ sung nhiều câu lệnh xác nhận thời gian chạy để xác thực dữ liệu đầu vào cho các lớp của chúng tôi và yêu cầu sửa đổi nhiều lần đối với các getters và setters. Nếu các khai báo phương thức này đã tồn tại trong các tệp .cpp, điều này sẽ biến thành một biên dịch lại sạch sẽ cho chúng ta, có thể mất ~ 30 phút trên máy tính xách tay của tôi.
Đó không phải là nói rằng tôi không chơi nhanh và bẩn với các quy tắc và đặt mọi thứ vào tệp .h khi triển khai một cái gì đó thực sự nhanh, nhưng đối với mã, tôi nghiêm túc về tất cả các mã (bất kể chiều dài) trong tệp .cpp. Đối với các dự án lớn (một số) các quy tắc có lý do, và theo chúng có thể là một đức hạnh.
Nói về điều đó, tôi chỉ nghĩ đến một tập lệnh Perl khác mà tôi có thể cùng nhau tìm ra vi phạm các nguyên tắc mã hóa. Thật tuyệt khi được phổ biến. :)
Trong điểm đầu tiên của bạn, tôi nghĩ bạn có nghĩa là tuyên bố thay vì định nghĩa. –
- 1. Tìm kiểu khai báo của phương thức
- 2. Loại trả về biến của phương thức trong C#
- 3. Hiệu quả của việc khai báo biến cuối cùng trong các phương thức là gì?
- 4. xCode/khai báo các phương thức tĩnh trong lớp
- 5. Tạo danh sách các phương thức của một lớp với các kiểu phương thức
- 6. Phương thức EquInfo để khai báo Loại
- 7. Phương thức khai báo ưu tiên trong một lớp
- 8. Chỉ nhận Phương thức của các phương thức được bảo vệ và công khai?
- 9. Truy cập các phương thức "Công khai" từ các phương thức "Riêng tư" trong lớp javascript
- 10. Các phương thức đồng bộ trong C#
- 11. Quy tắc của phương thức khai báo trong Obj-c là gì? Tôi có thể sử dụng một phương thức mà không cần khai báo trực tiếp không?
- 12. Java Enums: Phương thức triển khai sau khi khai báo?
- 13. Có bao nhiêu trường hợp, các biến tĩnh được khai báo trong một phương thức?
- 14. Triển khai mẫu Phương thức mẫu trong C#
- 15. Ý kiến của bạn về việc khai báo hằng số bên trong các phương thức ...?
- 16. Tại sao Java autoboxing không mở rộng đến phương thức invocations của các phương thức của các kiểu autobox?
- 17. Lập trình giảng dạy và các phương pháp chính thức
- 18. Tự động gán phương thức/Phương thức như biến
- 19. biến tĩnh trong phương thức gọi
- 20. Khai báo mảng dưới dạng kiểu trả về trong khai báo phương thức lớp gen trong Clojure
- 21. Tôi có thể khai báo một biến kiểu 'giao thức' trong giao diện Objective-C không?
- 22. Chi phí của các phương thức nội tuyến trong C#
- 23. LD_PRELOAD cho các phương thức lớp C++
- 24. Phương thức kiểu nhà máy Enum
- 25. Tại sao các hằng số enum phải được khai báo trước bất kỳ biến nào khác và khai báo phương thức trong một kiểu enum?
- 26. Chỉ nhận các phương thức được khai báo của một lớp trong PHP
- 27. Thực hành tốt nhất của Junit: Phương thức công khai gọi nhiều phương thức riêng tư
- 28. Các phương thức có nên ném RuntimeException cho biết nó trong chữ ký phương thức?
- 29. Tại sao các phương thức giao diện C# không được khai báo trừu tượng hoặc ảo?
- 30. Nhận kiểu đối số theo phương thức
"Ẩn từ goto-zealots" thì giống như vậy. Trong kinh nghiệm hạn chế của tôi, có thể có LOTS của những thanh() {return m_bar; } "getters", vì vậy bạn đang thêm lộn xộn để không có lợi ích. Một thành viên-ref là rất khác nhau trong hiệu suất từ bất kỳ loại tính toán thực tế, bạn có muốn ẩn mà thực sự? – pngaz