Trochę bardziej gadatliwy niż Meyers, ale mógłbym to zrobić:
class X {
private:
// This method MUST NOT be called except from boilerplate accessors.
Z &_getZ(size_t index) const {
return something;
}
// boilerplate accessors
public:
Z &getZ(size_t index) { return _getZ(index); }
const Z &getZ(size_t index) const { return _getZ(index); }
};
Metoda prywatna ma niepożądaną właściwość polegającą na tym, że zwraca nie-stałą Z i dla stałej instancji, dlatego jest prywatna. Prywatne metody mogą łamać niezmienniki interfejsu zewnętrznego (w tym przypadku pożądanym niezmiennikiem jest „obiekt stały nie może być modyfikowany poprzez referencje uzyskane przez niego do obiektów, które posiada”).
Zauważ, że komentarze są częścią wzorca - interfejs _getZ określa, że nigdy nie można go wywoływać (poza akcesoriami, oczywiście): i tak nie ma żadnych korzyści, ponieważ jest to 1 dodatkowy znak do wpisania i nie będzie skutkuje mniejszym lub szybszym kodem. Wywołanie metody jest równoważne z wywołaniem jednego z akcesorów za pomocą const_cast, a ty też tego nie chciałbyś zrobić. Jeśli martwisz się, że błędy będą oczywiste (a to uczciwy cel), nazwij to const_cast_getZ zamiast _getZ.
Nawiasem mówiąc, doceniam rozwiązanie Meyersa. Nie mam przeciwko temu filozoficznego sprzeciwu. Osobiście jednak wolę odrobinę kontrolowanego powtarzania i metodę prywatną, którą można wywołać tylko w ściśle ściśle kontrolowanych okolicznościach, niż metodę, która wygląda jak szum linii. Wybierz swoją truciznę i trzymaj się jej.
[Edycja: Kevin słusznie zauważył, że _getZ może chcieć wywołać kolejną metodę (powiedzmy generateZ), która jest wyspecjalizowana w tej samej zasadzie co getZ. W takim przypadku _getZ zobaczyłby const Z i musiałby go const_cast przed powrotem. Nadal jest to bezpieczne, ponieważ akcesorium do płyty kotłowej porządkuje wszystko, ale nie jest szczególnie oczywiste, że jest bezpieczne. Ponadto, jeśli to zrobisz, a następnie zmienisz generatorZ, aby zawsze zwracał stałą, musisz również zmienić getZ, aby zawsze zwracał stałą, ale kompilator nie powie ci, że to zrobisz.
Ten ostatni punkt dotyczący kompilatora jest również zgodny z zalecanym wzorcem Meyersa, ale pierwszy punkt dotyczący nieoczywistego const_cast nie jest. Podsumowując, myślę, że jeśli _getZ okaże się, że potrzebuje const_cast dla jego wartości zwracanej, wówczas ten wzór traci dużo swojej wartości w porównaniu z wartością Meyersa. Ponieważ ma również wady w porównaniu do Meyersa, myślę, że w tej sytuacji przeszedłbym na jego. Refaktoryzacja od jednego do drugiego jest łatwa - nie wpływa na żaden inny poprawny kod w klasie, ponieważ tylko niepoprawny kod i płyta główna wywołują _getZ.]