2010-03-20 20 views

Trả lời

7

Nếu bạn muốn sử dụng mẫu trong một đơn vị dịch khác (tức là một tệp nguồn khác), bạn nên (hầu như luôn luôn) xác định nó trong tệp tiêu đề. (Có những ngoại lệ, như các bình luận bên dưới chỉ ra, nhưng IMHO đây là một nguyên tắc tốt.)

Cùng áp dụng nếu bạn muốn sử dụng chức năng nội tuyến từ một đơn vị dịch thuật khác.

Nếu không, bạn nên đặt triển khai vào tệp .cpp riêng biệt để giảm thiểu phụ thuộc.

+2

Đối với mẫu, không đúng là bạn phải đặt định nghĩa hàm (thành viên) trong tệp tiêu đề. Bạn có thể đặt các định nghĩa trong một tệp nguồn và sử dụng mẫu instantiation để tạo ra các chuyên ngành cụ thể có sẵn ... –

+0

@STingRaySC Vâng, tôi đã có một số ký ức mơ hồ từ C++ Templates rằng có thể, mặc dù tôi chưa bao giờ tự làm. Tuy nhiên, tôi đã cố gắng đưa ra một quy tắc chung cho những người mới bắt đầu và hầu như luôn luôn áp dụng. Đi vào các trường hợp đặc biệt là dành cho các chuyên gia (trong đó tôi không phải là :-) –

+0

Và bạn không phải cung cấp việc triển khai mẫu trong tệp tiêu đề nếu trình biên dịch của bạn hỗ trợ 'export' – smerlin

3

Hiểu vấn đề này về cơ bản là hiểu cách các đơn vị biên dịch C++ hoạt động. Những thứ trong các tệp tiêu đề về cơ bản được dán vào mã nguồn của một bó toàn bộ các đơn vị biên dịch theo các câu lệnh #include. Mỗi đơn vị biên dịch được biên dịch thành một tệp đối tượng, các tệp đối tượng được liên kết và bạn nhận được xung đột vì các công cụ đó được nhân rộng khắp nơi.

Trường hợp ngoại lệ là những thứ mà ít nhất không đi vào tệp đối tượng vì trình biên dịch giao dịch trực tiếp với chúng (ví dụ: hàm nội tuyến) và những thứ không thể được biên dịch trong một đơn vị khác vì chúng không được định nghĩa hoàn toàn (mẫu). Các chức năng mẫu thường là được khởi tạo giống hệt nhau trong nhiều đơn vị biên dịch và trình liên kết có các tính năng đặc biệt để loại bỏ các bản sao.

Điều này có nghĩa là việc tách giao diện và triển khai thành tệp tiêu đề và nội dung không phải là rất sạch sẽ. Ada có sự tách biệt rõ ràng hơn nhiều - nhưng một quá trình xây dựng phức tạp hơn để bù đắp cho IIRC. Java chỉ đơn giản là thả các tệp riêng biệt cho giao diện và điều thực hiện.

Liên kết đã trở nên tinh vi hơn trong nhiều năm và đã thực hiện một số công việc của trình biên dịch, và rất nhiều giải thích này chỉ đơn giản là sai những ngày này, nhưng các mẫu cơ bản vẫn còn. Các hàm mẫu và các hàm nội tuyến có thể (và thường cần phải) đi trong tiêu đề, cùng với tất cả các khai báo được chia sẻ không-trực tiếp-đối tượng-mã-đối ​​tượng của bạn. Định nghĩa hàm bình thường không được nằm trong tệp tiêu đề.

+0

Thực ra, các trình liên kết không phải là thông minh về bản năng 'template'. Về cơ bản, họ sẽ thực hiện lần đầu tiên họ gặp phải và dựa vào ** ODR ** (Quy tắc một định nghĩa). Có thể dẫn đến khó tìm lỗi nếu chỉ một phần của 'Foo ' instanciations sử dụng một chuyên môn! –

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