Да, есть.
Я уже некоторое время пытаюсь защищать метод, основная идея в том, чтобы использовать класс Key
.
Хотя это на самом деле не удаляет использование friend
, оно сокращает набор открытых деталей реализации.
class set;
// 1. Define the Key class
class set_key: noncopyable { friend class set; set_key() {} ~set_key() {} };
class set
{
// 2. Define the iterator
class iterator
{
public:
void public_method();
void restricted_method(set_key&);
}; // class iterator
}; // class set
Теперь restricted_method
является общедоступным, поэтому set
не требуется особый доступ к iterator
. Однако его использование разрешено только тем, кто способен передать экземпляр set_key
... и, как правило, только set
может создать такой объект.
Обратите внимание, что set
может фактически передать объект set_key
кому-то другому, кому он доверяет. Это ключ в традиционном смысле: если вы дадите кому-то ключ от своей квартиры, он может передать его другому человеку. Однако из-за семантики класса ключей (не копируемого, только set
может создать и уничтожить его), это обычно ограничено продолжительностью области действия объекта key
.
Обратите внимание, что злой хак всегда возможен, а именно *((set_key*)0)
. Эта схема защищает от Мерфи, а не Макиавелли (в любом случае это невозможно в C ++).