2009-11-05 40 views
6

Vì tình bạn của lớp không được kế thừa trong C++, cách tốt nhất để "giả" là gì?Thừa kế tình bạn trong C++?

Tôi đã suy nghĩ về việc phơi bày giao diện riêng của lớp bạn bè thông qua các phương thức được bảo vệ trong lớp cơ sở được thừa kế, nhưng kết quả là phải viết (và duy trì) cùng một giao diện hai lần.

Có cách nào khác không?

Trả lời

6

Việc sử dụng phím là giải pháp khả thi.

Ý tưởng là bạn có thể mở khóa các hoạt động chỉ nếu bạn có một chính ... nhưng một ví dụ đáng ngàn trên chữ vì vậy hãy bổ nhào:

// Step 1: The key 
class NeedAccess; 

namespace details { class Key { friend NeedAccess; Key() {} }; } 

// Step 2: NeedAccess 
class NeedAccess 
{ 
protected: 
    static details::Key GetKey() { return details::Key(); } 
}; 

// Step 3: The big one 
class BigOne 
{ 
public: 
    void lockedMethod(details::Key); 
}; 

Các vấn đề của bản phúc chính constructable đang thảo luận. Tôi không thấy những gì bạn có thể đạt được bằng cách ngăn chặn nó.

Một lợi ích khác là bạn có thể có nhiều phím, tùy thuộc vào phương pháp bạn muốn truy cập, cách bạn trao tình bạn 'một phần' và bạn bè 'một phần' của bạn không thể gây rối với các bộ phận riêng của bạn, mặc dù tuyên bố nổi tiếng!

EDIT:

Phương pháp này được gọi là giới hạn hữu nghị, và đã được thảo luận trên comp.lang.c++.moderated.

Ưu điểm chính của phương pháp này so với Private Interface, là khớp nối rời, vì chỉ cần khai báo chuyển tiếp.

+0

Vì 'Khóa' là một lớp trống, nó có thực sự có bất kỳ hiệu ứng stack-wize/memory-wize nào hay trình biên dịch coi nó là" cú pháp "? – sold

+2

Một lớp trống vẫn còn 'nặng' một cái gì đó (ít nhất là một giá trị byte của dữ liệu, thường là do vấn đề liên kết nhiều hơn). Có một tối ưu hóa được gọi là Empty Base Optimization, bao gồm kế thừa từ lớp trống để tránh phát sinh chi phí này. Do đó bạn có thể chọn có 'NeedAccess' kế thừa riêng từ' Key' và trả về một tham chiếu thay vì một bản sao ... nhưng một tham chiếu cũng 'nặng' một cái gì đó. –

0

Không chắc nếu đây không phải là những gì bạn đã suy nghĩ về nhưng đây là một ví dụ Virtual Friend

2

Những đứa trẻ của lớp với frinedship cần phải hỏi có cha mẹ làm việc tiếp cận đối với họ.

class CrustyNeighbour 
{ 
    private: 
     friend class Bob; 
     void useWiFi(std::string const& data); 
}; 

class Bob 
{ 
    protected: 
     useWifi(CrustyNeighbour& neighbour,std::string const& data) 
     { neighbour.useWiFi(data);} 
}; 

class Mary: public Bob // Bob's offspring 
{ 
    void playHalo(WifiOwner& owner) // WifiOwner derived from CrustyNeighbour 
    { 
     useWifi(owner,gameData); // use wifi via his/her parent who access to eighbours wifi 
    } 
}; 
+0

+1 cho ví dụ của bạn. :-) – Tenner