2009-09-01 39 views
10

Là một nhà xây dựng công cộng trong một lớp trừu tượng một mã số? Làm cho hàm tạo được bảo vệ cung cấp tất cả quyền truy cập mà bạn có thể sử dụng. Quyền truy cập bổ sung duy nhất mà công khai cung cấp sẽ là cho phép các cá thể của lớp được khai báo là các biến trong phạm vi không thể truy cập các thành viên được bảo vệ của nó, nhưng các thể hiện của các lớp trừu tượng không thể được khai báo.Là một nhà xây dựng công cộng trong một lớp trừu tượng một mã số?

+0

Làm cách nào bạn có thể khai báo các biến của lớp trừu tượng? Tui bỏ lỡ điều gì vậy? – sbi

+0

Tôi nghĩ rằng OP có nghĩa là phương pháp, như trong 'phương pháp thành viên được bảo vệ.' – quamrana

+0

Tôi vẫn không hiểu. Bạn có thể cho thấy một ví dụ? – sbi

Trả lời

4

ý kiến ​​của tôi sẽ là nhà xây dựng công cộng có thể được nhìn thấy khó hiểu, và như bạn nói làm cho nó được bảo vệ sẽ là chính xác. Tôi sẽ nói rằng một nhà xây dựng được bảo vệ củng cố một cách chính xác ấn tượng rằng việc sử dụng hợp lý duy nhất của một lớp trừu tượng là lấy được từ nó.

Thực tế, bạn chỉ cần khai báo một hàm tạo trong lớp trừu tượng nếu nó cần thực hiện điều gì đó, ví dụ. khởi tạo thành viên riêng của mình. Sau đó tôi mong đợi sẽ có các hàm thành viên được bảo vệ khác hữu ích cho các lớp dẫn xuất.

EDIT:

Kể từ khi không có ai đăng bài bất kỳ mã và @sbi hỏi đối với một số trong một chú thích OP, tôi nghĩ tôi sẽ đăng một số:

class Base: 
{ 
public:   // The question is: should the ctor be public or protected? 
// protected: 
    Base():i(0){} // ctor is necessary to initialise private member variable 
public: 
    virtual ~Base(){} // dtor is virtual (but thats another story) 
        // pure virtual method renders the whole class abstract 
    virtual void setValue(void)=0; 
protected: 
    int getValue(void){ return i;} 
private: 
    int i; 
}; 

Base b1; // Illegal since Base is abstract, even if ctor is public 
Base& b2=makeBase(); //We can point to, or refer to a Base 
b2.setValue(); // We're not sure what this does, but we can call it. 
b2.getValue(); // Illegal since getValue is protected 
3

Như bạn nói, không cần phải cung cấp hàm xây dựng công khai của lớp trừu tượng, cũng không có thể bị lạm dụng, nếu bạn cung cấp hàm tạo công khai.

Tuy nhiên, bạn có thể xem xét tuyên bố hàm tạo là công khai như là gợi ý cho việc cấu trúc các lớp bắt nguồn từ lớp trừu tượng.

+2

Bạn có thể giải thích câu thứ hai của mình không? Tôi không hiểu đề xuất có thể là gì. – quamrana

+1

Tôi nghĩ rằng ctors công cộng sẽ khuyên bạn nên thực hiện các lớp học một phương tiện thiết kế giao diện công cộng. Giống như, một lớp "Window" trừu tượng có thể có một ctor công khai có tham số "Window * parent". Nó sẽ khuyên bạn nên tạo ra các lớp để cung cấp nó như là một nhà xây dựng công cộng quá, mà sẽ là một phần của giao diện. –

+0

Tôi nghĩ rằng có thể là trường hợp - tôi muốn nói rằng nó sai. Tôi sẽ nói rằng trong trường hợp của một ctor, nó cần được bảo vệ và lấy các tham số cần thiết, hoàn toàn độc lập với những gì các lớp dẫn xuất nên làm. Tuy nhiên, bất kỳ hàm thành viên ảo thuần túy nào khác, ** phải là một dấu hiệu mạnh mẽ cho thấy rằng một lớp lá cần phải thực hiện những điều này với (rõ ràng) cùng một mức truy cập và các tham số. – quamrana

11

Tôi đã đọc nó trong ít nhất một hướng dẫn mã hóa mà các nhà xây dựng của các lớp trừu tượng không được công khai - Tôi nghĩ rằng quy tắc có ý nghĩa với lý do bạn đưa ra.

Tuy nhiên, tôi không thể tưởng tượng được trường hợp công khai sẽ khiến mọi thứ trở nên sai. Vì vậy, tôi sẽ không đi xa như nói rằng đó là một mùi mã. Tôi thấy các nhà xây dựng được bảo vệ như là một tài sản "tốt để có" :)

+1

Đồng ý, nhà xây dựng được bảo vệ khai thác thực tế là lớp không thể được khởi tạo trực tiếp, vì vậy nó là một "thuộc tính tốt" từ quan điểm lập trình, ngay cả khi trình biên dịch không thực sự quan tâm đến nó. –

+2

Hướng dẫn mã hóa có nghĩa vụ bảo vệ bạn khỏi những điều xấu có thể xảy ra. Vì bạn không thể xây dựng một lớp trừu tượng, tôi không thấy hướng dẫn này đang bảo vệ bạn từ đâu và do đó cảm thấy có sự phân xử. –

+0

Họ nói bằng cách làm cho nó được bảo vệ, bạn làm cho nó rõ ràng rằng nó không thể được sử dụng bởi các lớp dẫn xuất. Tôi nghi ngờ rằng đó là một lý do tương tự như với các nhà điều hành thành viên mới và xóa: Họ là các thành viên ngầm hoàn toàn tĩnh, nhưng nó là tốt để làm cho họ một cách rõ ràng tĩnh. Ở phía bên kia, định nghĩa trong lớp của các chức năng thành viên là hoàn toàn nội tuyến, và tôi sẽ nói rằng nó nghèo để làm cho chúng một cách rõ ràng nội tuyến. Cuối cùng, tôi nghĩ rằng vấn đề bảo vệ-constructor này là một vấn đề của hương vị. –

0

Hãy cẩn thận mặc dù đến khai báo rõ ràng/xác định hàm tạo bản sao được bảo vệ/riêng tư của bạn. Nếu bạn không trình biên dịch sẽ làm điều đó cho bạn. Xem scott meyers effective c++ mục 6.

+0

Bạn không có nghĩa là destuctor thay vì constructor? Có gì xấu về một constructor được tạo mặc định? – TimW

+0

Bạn nói đúng. Xin lỗi, tôi có nghĩa là xây dựng bản sao, khác toàn bộ điều không có ý nghĩa. – count0

0

Tôi muốn nói dấu hiệu xấu của nó vì một vài lý do.

Đầu tiên là nó có thể đánh lừa ai đó nghĩ rằng họ thực sự có thể gọi đó là thói quen.

Điều thứ hai là nó ngụ ý tác giả nghĩ bạn có thể gọi nó. Bây giờ bạn không biết liệu đó có phải là một phần quan trọng trong thiết kế của mình hay không.

+2

Tôi không nghĩ đó là những đối số hợp lệ. Không ai biết điều đầu tiên về thiết kế OO hoặc C++ sẽ nghĩ rằng bạn có thể gọi nó và thứ hai của tất cả trình biên dịch sẽ đưa ra một lỗi khi bạn thử. –

2

Tôi biết rằng tất cả mọi người rõ ràng không đồng ý, nhưng tôi không nghĩ rằng một ctor lớp trừu tượng nên được bảo vệ trừ khi giao diện bạn đang thiết kế có lý do cụ thể cho tất cả các lớp dẫn xuất cũng có một ctor được bảo vệ.

Lý do là khi bạn thiết kế một lớp trừu tượng, bạn đang thiết kế giao diện sẽ được triển khai bởi các lớp dẫn xuất. Các lớp có nguồn gốc nên thực hiện giao diện chính xác như nó được thiết kế trong lớp cơ sở. Giao diện được trình bày bởi một lớp cơ sở trừu tượng là một hợp đồng; không phá vỡ hợp đồng đó.

Hay nói cách khác, nếu bạn đang thay đổi giao diện, tại sao bạn lại bắt nguồn từ lớp đó ở nơi đầu tiên?

Đây là một câu trả lời tôn giáo, nhưng cái quái gì. ;-)

+1

@ Robert: Tôi hiểu lý do của bạn được đưa ra ở đây, nhưng tôi tin rằng nó không áp dụng cho người quản lý. Có, các chức năng thành viên công cộng và được bảo vệ khác (ngoại trừ ctor và dtor) cung cấp các giao diện là hợp đồng và bạn nên suy nghĩ kỹ trước khi thay đổi chúng. – quamrana

3

Lớp trừu tượng không bao giờ có thể được khởi tạo trực tiếp do các phương thức ảo thuần túy mà nó khai báo. Vì vậy, khai báo constructor như được bảo vệ chỉ thêm các mẹo bổ sung cho các lập trình viên.

Tôi đã xem đề xuất tuyên bố hàm tạo như được bảo vệ here, trong hướng dẫn kiểu Google. Và tôi đã đáp ứng các khuyến nghị tương tự trong một số tiêu chuẩn mã hóa của công ty khác. Vì vậy, điều này có vẻ giống như một thực hành tốt.

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