2009-10-22 43 views
12

Tôi muốn tạo lớp A lớp người bạn của lớp B. Tôi muốn làm điều này vì những tương tác này rất nhiều và A cần thay đổi nội bộ của lớp B (mà tôi không muốn tiết lộ bằng cách sử dụng công khai) . Nhưng tôi muốn chắc chắn rằng nó có quyền truy cập vào chỉ một vài chức năng được chọn không phải tất cả các chức năng.lớp bạn bè với quyền truy cập hạn chế

Ví dụ:

class A 
{ 
}; 

class B 
{ 
private: 
void setState(); 
void setFlags(); 
friend class A 
}; 

Tôi muốn Một để có thể truy cập vào setstate nhưng không setFlags ... Có một mẫu thiết kế hay một cách thoải mái để làm điều này hay tôi rời với cho phép truy cập đầy đủ hoặc không có truy cập ở tất cả trong trường hợp này.

Cảm ơn

+0

Ngoài thực tế là bạn có thể tùy chỉnh tài khoản của bạn (có rất nhiều điều chưa biết ...), đó là một câu hỏi rất thú vị. Tôi vẫn đang đùa giỡn với Key và Giao diện Riêng tư vào lúc này! –

Trả lời

26

Điều đó phụ thuộc vào ý bạn là "một cách tốt đẹp" :) Tại comp.lang.C++, chúng tôi đã kiểm tra cùng một câu hỏi trước đây. Bạn có thể thấy cuộc thảo luận đã tạo ra there.

IIRC, chúng tôi đã kết thúc bằng cách sử dụng phương pháp "người bạn của khóa lồng nhau". Áp dụng cho ví dụ của bạn, điều này sẽ mang lại:

class A 
{ 
}; 

class B 
{ 
public: 
    class Key{ 
     friend class A; 
     Key(); 
    }; 

    void setFlags(Key){setFlags();}   

private: 
    void setState(); 
    void setFlags(); 
}; 

Ý tưởng là các setFlags công cộng() phải được gọi với "Khóa", và chỉ có bạn bè của Key có thể tạo ra một, như ctor của nó là tư nhân.

+0

+1: Tôi chưa từng thấy điều này trước đây - thực sự rất thông minh. –

+0

Thực sự thông minh. Tôi thường dựa vào một 'hợp đồng' vì tôi đã không chiến đấu với bất kỳ cách nào để làm điều này ... bạn học mỗi ngày! –

+0

Nhân tiện, trong câu hỏi OP, anh ấy muốn truy cập setState, chứ không phải setFlags ... vâng tôi là người khổng lồ ... –

7

Một cách tiếp cận là thông qua giao diện rõ ràng, bởi vì implementor của một giao diện có thể chọn những người mà họ cung cấp cho họ để:

class NearlyPrivateInterface { 
public: 
    virtual void setState() = 0; 
    virtual void setFlags() = 0; 
}; 

class A { 
public: 
    void attach(NearlyPrivateInterface* instanceOfB); 
}; 

class B: private NearlyPrivateInterface { 
public: 
    void attach(A& a) { a.attach(this); } 
}; 
+1

Đó là mẫu giao diện riêng tư: http://www.objectmentor.com/resources/articles/privateInterface.pdf –

2

Bạn có thể làm điều sau đây ..

class A{ 
}; 

class B{ 
private: 
    void setFlags(); 
protected: 
    void setState(); 

}; 

class RestrictedB :public B{ 
    friend class A; 
}; 
Các vấn đề liên quan