2012-01-31 23 views
11

Giả sử tôi có lớp học như thế này (giản thể):Mẫu thiết kế này là gì? Làm thế nào để sử dụng nó?

class Foo_p; 
class Foo 
{ 
private: 
    Foo_p *p; 
public: 
    Foo(); 
    /* methods, etc... */ 
}; 

Lớp này là một phần của một API. Foo_p là tất cả các phần riêng của lớp, không phải là được khai báo trong lớp Foo như thường lệ, mà là trong một lớp được khai báo chuyển tiếp riêng biệt chỉ được sử dụng bởi triển khai cơ bản không hiển thị ở bên ngoài.

Tôi đã thấy mẫu này được sử dụng trong một vài dự án, có tên cho nó không?

Ngoài ra, làm cách nào để sử dụng nó đúng cách (ví dụ: an toàn ngoại lệ, v.v.)? Nên triển khai thực tế ở đâu? Trong lớp Foo, như thường lệ, chỉ sử dụng Foo_p để lưu trữ dữ liệu, hoặc trong lớp Foo_p với Foo chỉ là một trình bao bọc?

Trả lời

8

Điều này được biết là PIMPL. thực hiện riêng tư/con trỏ đến riêng tư. Lớp học, Foo_p, lớp học của bạn sẽ được triển khai một cách riêng tư và được truy cập thông qua con trỏ đến nó thay vì hiển thị lớp thực cho khách hàng, họ chỉ có thể xem giao diện công khai mà bạn đã chọn để hiển thị. Về cơ bản, nó tóm tắt từ tiêu đề các dấu tích chi tiết triển khai hiện diện trong các thành viên protectedprivate.

Tôi thấy nó khó sử dụng trong VC++ - nó phá vỡ hoàn thành mã. Sẽ rất hữu ích nếu bạn rất chắc chắn về việc triển khai của mình và không muốn các thành viên privateprotected hiển thị trong tiêu đề.

Tôi đặt triển khai thực tế của lớp Foo_p trong tệp cpp cho lớp Foo, mặc dù điều này có thể là nguyên nhân của việc hoàn thành mã, ít nhất tôi không phải chịu rủi ro của lớp đang được sử dụng lại bằng cách bao gồm tiêu đề của nó.

+0

Đừng cả các tiêu đề và mức độ bảo vệ bình thường (public/private) "về cơ bản giấu việc thực hiện"? –

+0

@Matthew: Thật không may, không. Bạn phải bao gồm các tiêu đề triển khai, thường có thể khó chịu khi chúng phụ thuộc vào ví dụ các tiêu đề của Windows, điều này rất đáng tiếc. – Puppy

+0

@MatthewFlaschen: Có, nhưng chỉ theo nghĩa là bạn không thể truy cập nó, nhưng bạn vẫn có thể thấy * nó, khi nhìn vào mã. – bitmask

8

Đó là pimpl ngữ

Xem

+0

Cảm ơn bạn đã liên kết! – kralyk

+0

Liên kết đã chết: ( – pmb

+1

@pmb Cảm ơn gợi ý. Cố định tất cả ba liên kết .Oo permalinks ... khi chúng hoạt động, chúng rất đẹp :( – sehe

2

Đó là một con trỏ d, là một loại con trỏ đục. Tương tự như thành ngữ PIMPL.

Một loại con trỏ mờ thường được sử dụng trong khai báo lớp C++ là con trỏ d. Con trỏ d là thành viên dữ liệu riêng tư duy nhất của lớp và trỏ đến một thể hiện của một cấu trúc. Được đặt tên bởi Arnt Gulbrandsen của Trolltech, phương pháp này cho phép khai báo lớp để bỏ qua các thành viên dữ liệu riêng lẻ , ngoại trừ chính con trỏ d.[6] Kết quả là nhiều triển khai của lớp bị ẩn khỏi chế độ xem, việc thêm thành viên dữ liệu mới vào cấu trúc riêng sẽ không ảnh hưởng đến khả năng tương thích nhị phân và tệp tiêu đề có chứa khai báo lớp chỉ phải # bao gồm các tệp khác cần thiết cho giao diện lớp học, thay vì để triển khai. Bên cạnh lợi ích , việc biên dịch nhanh hơn vì tệp tiêu đề thay đổi ít thường xuyên hơn . Con trỏ d được sử dụng nhiều trong các thư viện Qt và KDE.

https://en.wikipedia.org/wiki/Opaque_pointer#C.2B.2B

+0

Trích dẫn nguồn của bạn. –

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