2010-04-11 27 views
6

A ++ lớp C "truyền thống" (chỉ một số tờ khai ngẫu nhiên) có thể giống như sau:C++ Lớp Truy cập Specifier verbosity

class Foo 
{ 
public: 
    Foo(); 
    explicit Foo(const std::string&); 
    ~Foo(); 

    enum FooState 
    { 
    Idle, Busy, Unknown 
    }; 

    FooState GetState() const; 
    bool GetBar() const; 
    void SetBaz(int); 

private: 
    struct FooPartialImpl; 

    void HelperFunction1(); 
    void HelperFunction2(); 
    void HelperFunction3(); 

    FooPartialImpl* m_impl; // smart ptr 
    FooState m_state; 
    bool m_bar; 
    int m_baz; 
}; 

tôi luôn luôn tìm thấy kiểu này đặc điểm kỹ thuật cấp độ truy cập xấu xí và khó khăn để làm theo nếu các lập trình viên gốc đã không tổ chức "vùng truy cập" của mình một cách gọn gàng.


Lấy một cái nhìn tại các đoạn mã tương tự trong một # kiểu Java/C, ta có:

class Foo 
{ 
    public: Foo(); 
    public: explicit Foo(const std::string&); 
    public: ~Foo(); 

    public: enum FooState 
    { 
    Idle, Busy, Unknown 
    }; 

    public: FooState GetState() const; 
    public: bool GetBar() const; 
    public: void SetBaz(int); 

    private: struct FooPartialImpl; 

    private: void HelperFunction1(); 
    private: void HelperFunction2(); 
    private: void HelperFunction3(); 

    private: FooPartialImpl* m_impl; // smart ptr 
    private: FooState m_state; 
    private: bool m_bar; 
    private: int m_baz; 
}; 

Theo tôi, đây là dễ dàng hơn để đọc trong một tiêu đề vì sự xác định quyền truy cập là đúng bên cạnh mục tiêu, và không phải là một loạt các dòng đi. Tôi thấy điều này đặc biệt đúng khi làm việc với mã mẫu tiêu đề chỉ không được tách thành cặp "* .hpp/*. Inl" thông thường. Trong kịch bản đó, kích thước của việc triển khai chức năng áp đảo thông tin nhỏ nhưng quan trọng này.


Câu hỏi của tôi rất đơn giản và bắt nguồn từ thực tế là tôi chưa bao giờ thấy bất kỳ ai khác tích cực làm điều này trong mã C++ của họ.

Giả sử rằng tôi không có IDE có khả năng "Chế độ xem lớp", có bất kỳ hạn chế rõ ràng nào khi sử dụng mức độ chi tiết này không?

Bất kỳ đề xuất kiểu nào khác đều được hoan nghênh!

+0

Đối với định nghĩa hàm mẫu trực tiếp trong định nghĩa lớp ... điều đó không quan trọng đối với một lớp lót nhưng thực sự khó hiểu giao diện lớp ngay sau khi nó phát triển. Cá nhân tôi không tách tiêu đề của tôi trong .h/.i, đặt tôi đặt định nghĩa của các hàm * lớn * ở cuối tệp. –

Trả lời

10

"Khi ở Rome, hãy làm như người La Mã làm."

Tôi đã dành rất nhiều thời gian với Java, như kiểu chỉ định các bộ định danh truy cập cho từng trường và phương thức riêng biệt. Tuy nhiên khi tôi lập trình bằng C++, tôi luôn sử dụng kiểu được hiển thị trong đoạn mã đầu tiên của bạn.

+0

Rất vui được thấy tên của bạn đã được sửa: D –

+0

Vâng, đó là một điều tốt – GManNickG

+0

Có một quy trình nào không? Tôi đã tự đặt tên cho mình sau một vài hạt… – Potatoswatter

5

Cá nhân tôi thấy rất khó chịu khi phải chỉ định vòng loại truy cập cho mọi biểu tượng. Nó làm cho mọi thứ khó đọc hơn, không dễ dàng hơn, và khuyến khích thói quen xấu là tự do trộn lẫn các công cụ riêng tư và công khai trong suốt định nghĩa lớp. Tôi thấy loại lộn xộn này mọi lúc. Trong C#, tôi cố gắng giảm thiểu điều này với #region private, vv, hy vọng khuyến khích các nhà duy trì trong tương lai giữ mọi thứ sạch sẽ.

+0

Ha! Tôi thắng 4 giây. +1 :) –

+1

Re: khu vực; Khi tôi làm việc trong VS và viết mã dành riêng cho Windows, tôi cũng cố gắng sử dụng chỉ thị #pragma region/endregion. Nó khá tốt đẹp mà VS hỗ trợ này cho C + +. – PolyTex

1

Không có gì sai với nó, mặc dù bạn sẽ nhướn lông mày. Ưu điểm chính của việc giữ riêng các đặc tả truy cập là nó khuyến khích đặt tất cả các thành viên và phương thức riêng ở trên cùng của lớp - cùng nhau.

Nếu lớp của bạn quá lớn để vừa với một màn hình, nó có thể được chia nhỏ thành nhiều lớp và/hoặc bất kỳ hàm nội tuyến ngầm nào phải được khai báo rõ ràng với việc triển khai được chuyển ra khỏi lớp.

+0

Tôi không biết nó là gì, nhưng phiên bản đầu tiên chỉ trông "tắt" với tôi. Có lẽ vì tôi đã làm việc chủ yếu ở C# trong vài tuần qua? – PolyTex

+0

@PolyTex: Có thể, nhưng trong trường hợp đó tôi trì hoãn Rahul G - tôi ghét câu trả lời của Unicorns. (Tôi không thể tin rằng tôi chỉ nghiêm túc gõ rằng ...) –

+0

Bạn không cần phải có bao gồm * Tôi ghét Unicorns * trong tên của tôi. Tôi đã chỉnh sửa tên của mình vào ngày 1 tháng 4 và bây giờ tôi bị kẹt với nó trong một tháng. :( – missingfaktor

0

Những bất lợi của phương pháp thứ hai là hiếm khi được thực hiện, và không phải là một ý tưởng tốt để gây ngạc nhiên cho các nhà phát triển khác theo cách này, và nó yêu cầu bộ sửa đổi truy cập phải gõ hàng triệu lần. Sử dụng cách tiếp cận truyền thống sẽ tiết kiệm được việc không cần thiết phải gõ công cụ sửa đổi nhiều lần và cũng là cách tiếp cận dự kiến.

0

Thật vậy, ngữ nghĩa nó không có sự khác biệt nhưng bạn sẽ làm cho bản thân và đồng nghiệp của bạn một ưu tiên lớn nếu bạn chỉ tuân theo những gì được chấp nhận.

Cá nhân tôi thích lớp học của tôi như vậy:

struct S { 
    S(int m) : m(m) { } 
    S(const S& o); 
    S& operator=(const S& o); 

    void f() const; 
    std::string g(); 

private: 
    void help(); 

private: 
    int m; 
}; 

Nhưng tôi sẽ thay đổi cách cư xử của tôi mà không suy nghĩ hai lần nếu tôi cam kết thành một kho lưu trữ mà không phải là nghiêm của tôi, bởi vì tôi biết làm thế nào đánh giá cao tôi muốn được nếu ai đó sẽ cam kết mã của họ vào kho của tôi theo phong tục của tôi.

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