2009-04-18 38 views
6

Tôi nhận ra rằng có rất nhiều câu hỏi liên quan đến các lớp bạn bè trong C++. Câu hỏi của tôi, mặc dù, được gắn với một kịch bản cụ thể. Với mã dưới đây, có thích hợp để sử dụng bạn bè theo cách như vậy không?Lớp học bạn bè C++

class Software 
{ 
    friend class SoftwareProducer; 

    SoftwareProducer* m_producer; 
    int m_key; 
    // Only producers can produce software 
    Software(SoftwareProducer* producer) : m_producer(producer) { } 

public: 
    void buy() 
    { 
     m_key = m_producer->next_key(); 
    } 
}; 

class SoftwareProducer 
{ 
    friend class Software; 

public: 
    Software* produce() 
    { 
     return new Software(this); 
    } 

private: 
    // Only software from this producer can get a valid key for registration 
    int next_key() 
    { 
     return ...; 
    } 
}; 

Cảm ơn,

Trân trọng,

Trả lời

8

Chắc chắn, điều đó hoàn toàn hợp lý. Về cơ bản những gì bạn đã làm là rất giống với một mô hình nhà máy. Tôi thấy không có vấn đề với điều đó vì mã của bạn dường như ngụ ý rằng mọi đối tượng Phần mềm phải có một con trỏ đến người tạo của nó.

Mặc dù, thông thường bạn có thể tránh phải có các lớp "Người quản lý" như Nhà sản xuất phần mềm và chỉ có các phương pháp tĩnh trong Phần mềm. Vì có vẻ như sẽ chỉ có một Nhà sản xuất phần mềm. Một cái gì đó giống như có lẽ đây:

class Software { 
private: 
    Software() : m_key(0) { /* whatever */ } 
public: 
    void buy() { m_key = new_key(); } 
public: 
    static Software *create() { return new Software; } 
private: 
    static int new_key() { static int example_id = 1; return example_id++; } 
private: 
    int m_key; 
}; 

Sau đó, bạn chỉ có thể làm điều này:

Software *soft = Software::create(); 
soft->buy(); 

Tất nhiên nếu bạn có kế hoạch về việc có đối tượng nhiều hơn một SoftwareProducer, sau đó những gì bạn đã làm có vẻ thích hợp.

1

Tôi nghĩ việc làm cho Nhà sản xuất phần mềm như một người bạn của Phần mềm là chấp nhận được nhưng tôi không thấy lý do gì khiến Phần mềm phải là bạn của lớp SoftwareProducer. Đó là sự phụ thuộc không cần thiết giữa chúng. Bạn có thể lấy khóa làm đối số hàm tạo cho lớp Phần mềm. Ngoài ra bạn có thể muốn làm cho destructor của lớp Software riêng tư để không ai ngoại trừ SoftwareProducer có thể phá hủy chúng.

+0

Tôi đã làm Phần mềm làm bạn của Nhà sản xuất phần mềm để có quyền truy cập vào phương thức next_key riêng tư. – Alex

+0

Không phải là cách khác? Để cho phép nhà xây dựng riêng của Phần mềm được gọi từ Nhà sản xuất Phần mềm, bạn cần phải làm cho Nhà sản xuất Phần mềm trở thành bạn của Phần mềm mà tôi đã nói là hợp lý. Nhưng bạn cũng đã làm cho phần mềm là một người bạn của SoftwateProducer để phương thức next_key() có thể được gọi mà tôi cảm thấy là không cần thiết. – Naveen

+0

Làm cách nào khác có thể một cá thể phần mềm truy cập phương thức next_key của nhà sản xuất nếu nó là riêng tư? – Alex

1

Tôi sẽ không thảo luận về vấn đề tình bạn, nhưng tôi có xu hướng không thích phụ thuộc theo chu kỳ. Phần mềm phụ thuộc vào SoftwareProducer phụ thuộc vào Phần mềm ... Tôi sẽ cố gắng tái cấu trúc lại.

Cũng lưu ý rằng mối quan hệ hữu nghị mở nội bộ thành tất cả trường hợp của lớp khác. Đó là càng nhiều càng nói rằng bình luận của bạn trong next_key là sai:

Làm next_key tin không cho phép bất kỳ lớp từ gọi nó, nhưng một khi bạn mở lên đến Software lớp, mọi phần mềm có thể gọi next_key trên tất cả Nhà sản xuất phần mềm.

+0

+1, bạn về mặt kỹ thuật lại: next_key() - bất kỳ Phần mềm nào có thể gọi nó - nhưng nó cũng không phải là rủi ro bảo mật vì bạn có quyền kiểm soát Định nghĩa và tình bạn của phần mềm không phải là quá trình chuyển đổi hoặc thừa kế. Ngoài ra, tốt nhất là tránh các phụ thuộc theo chu kỳ nếu có thể, nhưng đôi khi chúng cần thiết - bạn có thể đề xuất một sự thay thế tốt hơn trong trường hợp này không? –

+0

Thật vậy, tôi không thích phụ thuộc theo chu kỳ, đó là lý do tại sao tôi đăng câu hỏi này. Tôi đồng ý rằng đó là một ví dụ phức tạp (purpousely). – Alex

+1

Hầu hết các phụ thuộc cyclic có thể được loại bỏ bằng cách xác định giao diện và tùy thuộc vào chúng. Bây giờ, một khi bạn bắt đầu theo cách đó, sử dụng private + friend để kiểm soát truy cập sẽ trở nên khó khăn hơn nhiều. Tôi có lẽ sẽ di chuyển hoạt động mua ra khỏi Phần mềm và vào một Đại lý/Cửa hàng bên ngoài hoặc thậm chí là Nhà sản xuất phần mềm, và kiểm soát truy cập đẩy vào logic thay vì hệ thống kiểu. –

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