2013-04-19 24 views
5

Tôi hiểu rằng trong lập trình chung, các thuật toán được tách ra khỏi các vùng chứa. Vì vậy, sẽ không có ý nghĩa gì khi thực hiện một thuật toán chung như một phương thức thể hiện (cùng một thuật toán sẽ làm việc trên nhiều lớp cụ thể; chúng ta không muốn làm cho chúng kế thừa từ một ABC vì nó sẽ tăng số lượng các lớp).Tại sao Thư viện đồ thị Boost (nguồn) là một hàm toàn cục?

Nhưng trong trường hợp của source() chức năng trong Boost Graph Library, tôi không hiểu lý do tại sao nó là một chức năng toàn cầu và không phải là một phương pháp thể hiện của một lớp biểu đồ.

Theo như tôi có thể biết bằng cách đọc số BGL source code, source(e, g) cần biết chi tiết triển khai của biểu đồ và cạnh đối tượng được truyền cho nó; không đủ để chỉ biết các giao diện của chúng.

Vì vậy, source() không phải là một thuật toán chung. Nói cách khác, nó cần biết lớp bê tông của thể hiện đồ thị. Sau đó, tại sao không đặt nó trong cùng một lớp như một phương pháp dụ? Nó sẽ không sạch hơn/ít khó hiểu hơn là tạo ra một chức năng toàn cầu cần phải được tùy chỉnh cho mỗi lớp mà nó được gọi?

CẬP NHẬT

Mã nguồn liên quan:

// dwa 09/25/00 - needed to be more explicit so reverse_graph would work. 
    template <class Directed, class Vertex, 
     class OutEdgeListS, 
     class VertexListS, 
     class DirectedS, 
     class VertexProperty, 
     class EdgeProperty, 
     class GraphProperty, class EdgeListS> 
    inline Vertex 
    source(const detail::edge_base<Directed,Vertex>& e, 
     const adjacency_list<OutEdgeListS, VertexListS, DirectedS, 
       VertexProperty, EdgeProperty, GraphProperty, EdgeListS>&) 
    { 
    return e.m_source; 
    } 


namespace boost { 

    namespace detail { 

    template <typename Directed, typename Vertex> 
    struct edge_base 
    { 
     inline edge_base() {} 
     inline edge_base(Vertex s, Vertex d) 
     : m_source(s), m_target(d) { } 
     Vertex m_source; 
     Vertex m_target; 
    }; 
    } 
} 
+0

Không có nguồn lý do nào (a, b) không thể chuyên biệt dựa trên các loại tham số của nó. Không phải mọi thứ đều phải là một hàm thành viên. Một số chức năng miễn phí có thể được coi là một phần của giao diện của một lớp. Ngoài ra nó có thể hữu ích để có thể sử dụng source() như một shim. Nếu không đọc và hiểu mã (không thể truy cập trong vòng 2 lần nhấp vào liên kết của bạn), tôi không thể nói với bạn rằng vì tôi không sử dụng thư viện biểu đồ nhưng chúng có thể là những thứ cần xem xét. Ngoài ra, hãy gửi thư trực tiếp cho nhà phát triển BGL và hỏi về quyết định thiết kế của họ. Tôi hy vọng có một lý do chính đáng cho nó – Pete

+0

Có lý do nào khiến bạn phiền lòng không? – Pete

+2

http://www.drdobbs.com/cpp/how-non-member-functions-improve-encapsu/184401197 –

Trả lời

6

source(e, g) không phải là một thuật toán chung. Một phần của giao diện, thường được gọi là một khái niệm trong C++. Lý do là một hàm không phải là thành viên để nó có thể được thực hiện không xâm phạm. Ví dụ:

Ví dụ: bạn muốn std::multimap để triển khai khái niệm IncidenceGraph. Nếu thư viện biểu đồ yêu cầu source() là một hàm thành viên, bạn sẽ không may mắn, vì std::multimap không cung cấp chức năng này.

+0

Tôi chắc chắn đó là lý do. Nhưng tại sao lại thừa hưởng từ 'multimap' và thêm' source' như một hàm thành viên? – max

+0

@max Nó không phải là xấu, nó chỉ không giải quyết vấn đề làm cho 'std :: multimap' một' IncidenceGraph' –

+0

Nếu tôi hiểu bạn một cách chính xác, bạn đang nói về tình huống sau đây. Giả sử tôi được cho một đối tượng 'dữ liệu', là một thể hiện của' std :: multimap'. Tôi muốn giải thích 'dữ liệu' dưới dạng đồ thị bằng cách xử lý các giá trị khóa làm đỉnh đồ thị và giá trị được ánh xạ của nó dưới dạng danh sách kề. Tôi có thể thấy lý do tại sao phương pháp tiếp cận chức năng không phải thành viên hoạt động tốt ở đây. Nhưng điều gì sẽ xảy ra nếu tôi muốn coi 'dữ liệu' như một biểu đồ bằng cách sử dụng hai cách diễn giải khác nhau? Sau đó tôi cần phải viết hai bộ chức năng không phải là thành viên. Làm thế nào để tránh va chạm với nhau? BGL không yêu cầu tất cả chúng nằm trong cùng một không gian tên? – max

3

Trong C++, ta nên thích chức năng phi bạn không thành viên nơi người ta có thể làm như vậy. Nếu source có thể được thực hiện theo các thành viên công khai của các lớp học được thiết kế để hoạt động, nó phải nằm ngoài lớp học.

Điều này không liên quan gì đến việc thực hiện các thuật toán chung chung; nó là hoàn toàn về việc giảm số lượng mã có quyền truy cập vào/có thể làm hỏng trạng thái nội bộ của các thành viên riêng tư của lớp.

+0

Cảm ơn. Nó thực sự là một hàm không phải là bạn, bởi vì đối tượng mà nó truy cập chỉ có các thành viên công cộng (trên thực tế, nó là một cấu trúc).Tuy nhiên, tôi không nghĩ rằng tôi hiểu tại sao những thành viên này lại được công khai. Xem [bình luận trước đó của tôi] (http://stackoverflow.com/questions/16114616/why-is-boost-graph-librarys-source-a-global-function#comment23015326_16114616). – max

+0

@max tùy thuộc vào việc lớp/cấu trúc có nhằm ngăn chặn sự vi phạm bất biến. Trong trường hợp này, có lẽ hai đỉnh mà cấu trúc giữ không có bất biến thực sự nào phải được duy trì (tức là nó là hợp pháp nếu chúng là cùng một đỉnh?). Nếu không có bất biến thì tại sao các thành viên cần phải được tư nhân? Tính nhất quán? Ngoài ra, nó có thể chỉ là các nhà phát triển BGL không thể bị làm phiền để viết tất cả các mã keo. – Pete

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