Наследовать дружбу в C++?
Так как классовая дружба не наследуется в C++, как лучше ее "подделать"?
Я думал о том, чтобы показать частный интерфейс друга класса через защищенные методы в базовом классе, который должен быть унаследован, но это приводит к необходимости писать (и поддерживать) один и тот же интерфейс дважды.
Есть ли другие способы?
3 ответа
Использование ключа является возможным решением.
Идея состоит в том, что вы можете разблокировать операции, только если у вас есть ключ... но пример стоит тысячи слов, поэтому давайте углубимся:
// 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);
};
Вопрос о том, является ли ключ копируемым, подлежит обсуждению. Я не вижу, что вы можете получить, предотвращая это.
Еще одним преимуществом является то, что у вас может быть несколько ключей, в зависимости от того, к какому методу вы хотите получить доступ, таким образом вы предоставляете "частичную" дружбу, и ваши "частичные" друзья не могут возиться с вашими личными частями, несмотря на известное утверждение!
РЕДАКТИРОВАТЬ:
Этот метод называется Limited Friendship и обсуждался на comp.lang.C++. Moderated.
Основным преимуществом этого метода по сравнению с Private Interface является слабая связь, так как необходимы только предварительные объявления.
Дети класса с фриндшипом должны попросить одного из родителей сделать для них доступ.
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
}
};
Не уверен, что это не то, о чем вы уже думаете, но вот пример виртуального друга