2009-02-18 31 views
5

nềntập tin tiêu đề riêng biệt cho các lớp bê tông - C++

Tôi có một lớp trừu tượng, một cái gì đó giống như

class IConverter{ 
    public: 
    virtual void DoConvertion() = 0; 
}; 

Sẽ có nhiều lớp bê tông mà chỉ thực hiện DoConvertion phương pháp.

class TextConverter : public IConverter{ 
    public: 
    virtual void DoConvertion(){ 
     // my code goes here 
    } 
}; 

class ImageConverter : public IConverter{ 
    public: 
    virtual void DoConvertion(){ 
     // my code goes here 
    } 
}; 

Sẽ có nhiều triển khai cụ thể như thế này. Tôi đã tạo một tệp tiêu đề cho biết, CharacterConverter.h có lớp trừu tượng IConverter.

Câu hỏi

Kể từ khi lớp bê tông của tôi chỉ thực hiện DoConvertion phương pháp, nó là cần thiết để tạo tập tin tiêu đề riêng biệt cho mỗi lớp bê tông? Ý tôi là bắt buộc phải tạo ImageConverter.h, TextConverter.h và cứ thế cho tất cả các lớp cụ thể? Tất cả các tệp tiêu đề này sẽ chứa cùng mã như IConverter lớp trừu tượng.

Mọi suy nghĩ?

+0

Trên một điểm phong cách không liên quan, tôi có lẽ muốn dùng từ thực tế "chuyển đổi" (như trong DoConversion) như tên gọi phương pháp của bạn. – Joe

+0

DoConvertion không phải là tên phương thức. Tôi chỉ cần đặt nó ở đây để hiển thị mẫu. :) –

+0

Cũng làm cho destructor của IConverter ảo. Ngay cả khi bạn chỉ định nghĩa nội tuyến. –

Trả lời

1

Một cái gì đó bạn có thể xem xét, tùy thuộc vào phần còn lại của thiết kế, là một nhà máy, nơi lớp trừu tượng của bạn có phương pháp tĩnh (hoặc nhiều phương pháp tĩnh, tùy thuộc vào cách bạn triển khai nó) xây dựng lớp con phù hợp và trả về nó như một IConverter *. Với điều này, bạn chỉ có thể hiển thị định nghĩa trừu tượng trong tệp tiêu đề và có tất cả các định nghĩa lớp và triển khai lớp cụ thể trong một tệp .cpp đơn cùng với việc triển khai lớp siêu. Điều này hơi khó sử dụng nếu lớp con của bạn lớn, nhưng với các lớp nhỏ hơn, nó sẽ giảm số lượng tệp bạn phải quản lý.

Nhưng, như những người khác đã chỉ ra, nó cuối cùng là một cuộc gọi phán xét. Các vấn đề hiệu năng duy nhất sẽ liên quan đến việc biên dịch; nhiều tệp cpp hơn có thể mất (hơi) lâu hơn để biên dịch và nhiều tệp tiêu đề hơn có thể làm tăng phân tích phụ thuộc. Nhưng không có yêu cầu rằng mỗi tập tin tiêu đề có một cpp phù hợp và ngược lại câu.

Căn cứ ý kiến, tôi khuyên bạn nên một cấu trúc như thế này:

IConverter.h ==> định nghĩa của IConverter
Converters.h ==> định nghĩa của tất cả các lớp con
IConverter.cpp == > bao gồm IConverter.h và Converters.h, chứa chức năng trừu tượng IConverter (phương pháp nhà máy tĩnh và bất kỳ chức năng nào có thể kế thừa)
TextConvter.cpp, ImagerConverter.cpp, etc. ==> các tệp cpp riêng biệt cho mỗi phân lớp, mỗi tệp chứa IConverter .h và Converters.h

Điều này cho phép bạn chỉ bao gồm IConverter.h trong bất kỳ ứng dụng khách nào sử dụng chức năng của nhà máy và chức năng chung. Đặt tất cả các định nghĩa khác trong một tiêu đề duy nhất cho phép bạn củng cố nếu chúng giống nhau về cơ bản. Các tệp cpp riêng biệt cho phép bạn tận dụng các lợi ích của trình biên dịch được Brian đề cập. Bạn có thể nội tuyến các định nghĩa lớp con trong tập tin tiêu đề như đã đề cập, nhưng điều đó không thực sự mua cho bạn bất cứ điều gì. Trình biên dịch của bạn thường thông minh hơn bạn khi nói đến các tối ưu hóa như nội dòng.

+0

Vâng. Nó sử dụng một nhà máy để tạo ra các lớp con thích hợp. Thật không may, tôi không thể có nó trong một tệp CPP duy nhất vì việc triển khai sẽ lâu hơn đối với mỗi lớp cụ thể. Bạn có khuyên bạn nên giữ nó trong các tập tin tiêu đề và không sử dụng các tập tin CPP? Tôi lo lắng về các vấn đề hiệu suất mà nó có thể mang lại. –

+0

Không, bạn chắc chắn nên triển khai các tệp cpp. Bạn có thể dễ dàng có một tệp tiêu đề duy nhất với tất cả định nghĩa và mỗi tệp thực thi trong một tệp cpp riêng biệt. Vấn đề hiệu suất chính xác là những gì bạn lo lắng? – mbyrne215

+0

Đó là trợ giúp tuyệt vời. Cảm ơn –

1

Có thể bạn sẽ nhận được câu trả lời theo cả hai cách.

Tôi muốn nói, đối với bất kỳ người chuyển đổi tầm thường nào, có tất cả chúng trong một cặp .h/.cpp đơn là đủ và quá mức cần thiết để tách từng người thành một cặp. Tôi nghĩ rằng sự cân bằng của việc duy trì rất nhiều tập tin so với duy trì một loạt các phương pháp trong một tập tin duy nhất là giá trị nó trong trường hợp này.

Chuyển đổi phức tạp có thể xứng đáng với các cặp tệp riêng của chúng.

8

Không bắt buộc. Về cơ bản nó là một cuộc gọi phán xét.

Nếu việc thực hiện rất đơn giản cho mỗi lớp học mà bạn có thể đặt chúng tất cả trong một .h và một cpp

Nếu triển khai được lâu hơn một chút, sau đó nó có thể là sạch hơn để sử dụng một .h và .cpp riêng tệp cho mỗi tệp.

Một số ưu điểm của việc sử dụng một .h khác nhau/cpp cho mỗi lớp:

  • Nó sẽ giữ mã tổ chức và sạch
  • Giảm công việc biên dịch: Một sự thay đổi trong một trong những triển khai sẽ không cần biên dịch lại tất cả những người khác
  • Thời gian biên dịch nhanh hơn: Một số trình biên dịch có thể biên dịch nhiều tệp cùng một lúc, chẳng hạn như nút chuyển đổi của Visual Studio/MP. Với một số tệp, bạn sẽ có thời gian biên dịch nhanh hơn.
  • file khác chỉ có thể bao gồm những gì họ cần thay vì tất cả mọi thứ
  • thời gian liên kết nhanh hơn: thời gian liên kết sẽ giảm do gia tăng liên kết
  • Sử dụng điều khiển phiên bản, bạn có thể nhìn lại chỉ thay đổi cho một lớp được thừa kế riêng, thay vì phải trải qua tất cả các thay đổi được thực hiện đối với khối lượng lớn .hh /.cpp tập tin để tìm thấy rằng một sự thay đổi trong một lớp học có nguồn gốc cụ thể.
+0

Cảm ơn. Việc triển khai thực hiện lâu hơn một chút đối với các lớp cụ thể. Vì vậy, tôi lo lắng về sự khác biệt hiệu suất nếu tôi đặt nó trong tập tin tiêu đề. –

1

Bạn sẽ cần định nghĩa về các lớp cụ thể để tạo đối tượng, vì vậy bạn cần phải đặt các định nghĩa đó vào tệp .h ở đâu đó. Những tập tin bạn đặt chúng trong là tùy thuộc vào bạn.

+0

Cảm ơn. Nó sẽ làm cho bất kỳ vấn đề hiệu suất nếu tôi đặt lớp bê tông trong tập tin tiêu đề mà không cần tạo tập tin CPP cho mỗi? Tôi sẽ bao gồm tất cả các lớp cụ thể chỉ ở một nơi. –

+0

Nếu bạn muốn thực hiện đầy đủ từng lớp vào một tệp .h, bạn chỉ cần khai báo mỗi hàm là nội tuyến. Điều này có thể dẫn đến một đoạn mã nhỏ, vì bạn sẽ nhận được ít nhất một bản sao trong mỗi tệp mà bạn gọi nó - nhưng thường không quá lo lắng. Thậm chí có thể nhanh hơn. –

1

Câu trả lời hay nhất cho điều này là dễ đọc hơn. Một tệp nguồn dài sẽ khó khăn cho bạn và các lập trình viên khác để theo dõi. Mặt khác, nhiều tệp nguồn nhỏ (nửa màn hình đầy đủ) chỉ là xấu.

1

Một trong những điểm chính của việc tạo lớp giao diện để khách hàng có thể phụ thuộc vào giao diện trừu tượng hơn là triển khai cụ thể và sau đó bạn được tự do thay đổi triển khai mà không ảnh hưởng đến khách hàng.

Đưa các khai báo cụ thể vào cùng một tệp tiêu đề khi khai báo giao diện đánh bại điều này, vì vậy bây giờ nếu bạn thay đổi chi tiết triển khai của lớp cụ thể, khách hàng của bạn sẽ cần phải biên dịch lại.

1

Bạn có thể nên sử dụng nhà máy hoặc con trỏ hàm tốt hơn.

Tuy nhiên, một cách đặc biệt khó chịu mà bạn cần lưu ý là sử dụng macro để khai báo các lớp cụ thể của bạn. Ví dụ:

Ở dưới cùng của IConverter.h bao gồm vĩ mô

#define DECLARE_CONVERTER_CLASS(CLASS_NAME) \ 
class CLASS_NAME : public IConverter\ 
{ \ 
    public: \ 
    CLASS_NAME() {} \ 
    virtual void DoConversion(); \ 
}; \ 

Sau đó, trong MyConverter1.cpp

DECLARE_CONVERTER_CLASS(MyConverter1) 

virtual void MyConverter1::DoConversion() 
{ 
    ... 
} 

Yuck :-)

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