Sedikit lebih bertele-tele daripada Meyers, tetapi saya mungkin melakukan ini:
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); }
};
Metode pribadi memiliki properti yang tidak diinginkan yang mengembalikan non-const Z & untuk turunan const, yang mengapa itu pribadi. Metode privat dapat memecah invarian dari antarmuka eksternal (dalam hal ini invarian yang diinginkan adalah "objek const tidak dapat dimodifikasi melalui referensi yang diperoleh melaluinya ke objek yang memiliki-a").
Perhatikan bahwa komentar adalah bagian dari pola - antarmuka _getZ menentukan bahwa tidak pernah valid untuk menyebutnya (selain dari pengakses, tentu saja): bagaimanapun juga tidak ada manfaat yang mungkin untuk melakukannya, karena 1 karakter lagi untuk diketik dan tidak akan menghasilkan kode yang lebih kecil atau lebih cepat. Memanggil metode ini sama dengan memanggil salah satu accessors dengan const_cast, dan Anda juga tidak ingin melakukannya. Jika Anda khawatir akan membuat kesalahan menjadi jelas (dan itu adalah tujuan yang adil), sebut saja itu const_cast_getZ alih-alih _getZ.
Omong-omong, saya menghargai solusi Meyers. Saya tidak punya keberatan filosofis untuk itu. Namun, secara pribadi, saya lebih suka sedikit pengulangan terkontrol, dan metode pribadi yang hanya boleh disebut dalam keadaan tertentu yang dikontrol ketat, daripada metode yang terlihat seperti derau garis. Pilih racun Anda dan tetap menggunakannya.
[Sunting: Kevin dengan tepat menunjukkan bahwa _getZ mungkin ingin memanggil metode lebih lanjut (katakanlah generateZ) yang merupakan spesialisasi khusus dengan cara getZ yang sama. Dalam kasus ini, _getZ akan melihat const Z & dan harus const_cast sebelum kembali. Itu masih aman, karena accessor boiler mengatur segalanya, tetapi tidak terlalu jelas bahwa itu aman. Lebih jauh, jika Anda melakukan itu dan kemudian mengubah generateZ untuk selalu mengembalikan const, maka Anda juga perlu mengubah getZ untuk selalu mengembalikan const, tetapi kompiler tidak akan memberi tahu Anda bahwa Anda melakukannya.
Poin terakhir tentang kompiler juga berlaku untuk pola yang disarankan Meyers, tetapi poin pertama tentang const_cast yang tidak jelas tidak. Jadi pada keseimbangan saya berpikir bahwa jika _getZ ternyata membutuhkan const_cast untuk nilai pengembaliannya, maka pola ini kehilangan banyak nilainya dibandingkan dengan Meyers. Karena itu juga mengalami kerugian dibandingkan dengan Meyers, saya pikir saya akan beralih ke miliknya dalam situasi itu. Refactoring dari satu ke yang lain itu mudah - tidak memengaruhi kode lain yang valid di kelas, karena hanya kode yang tidak valid dan panggilan boilerplate _getZ.]