Użycie klucza jest możliwym rozwiązaniem.
Chodzi o to, że można odblokować operacje tylko jeśli masz klucza ... ale przykładem jest wart tysiące na słowie więc niech nurkowania:
// 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);
};
Sprawa klucz jest kopią constructable jest do dyskusji. Nie widzę, co możesz zyskać, zapobiegając temu.
Inną korzyścią jest to, że możesz mieć kilka kluczy, w zależności od metody, do której chcesz uzyskać dostęp, w ten sposób przyznajesz "częściową" przyjaźń, a twoi "częściowi" przyjaciele nie mogą sobie poradzić z prywatnymi częściami, pomimo sławne roszczenie!
EDIT:
Ta metoda nazywana jest ograniczona Przyjaźń i dyskutowano na comp.lang.c++.moderated.
Główną zaletą tej metody w porównaniu z Private Interface jest luźne połączenie, ponieważ potrzebne są tylko deklaracje forward.
Ponieważ 'Key' jest pustą klasą, czy faktycznie ma jakieś efekty stack-wize/memory-wize, czy też kompilator traktuje to tylko jako" syntaktic-sugar "? – sold
Pusta klasa nadal "waży" coś (co najmniej bajt wartości danych, często więcej z powodu problemów z wyrównaniem). Istnieje optymalizacja o nazwie Empty Base Optimization, która polega na dziedziczeniu z pustej klasy, aby uniknąć poniesienia tego obciążenia. Możesz więc wybrać opcję "NeedAccess" dziedziczącą prywatnie z 'Key' i zwracającą referencję zamiast kopii ... ale odwołanie również" waży "coś. –