Jawaban mengapa kita meletakkan variabel anggota pribadi dalam header C ++ adalah bahwa ukuran kelas harus diketahui pada titik-titik di mana instance dideklarasikan sehingga kompiler dapat menghasilkan kode yang bergerak dengan tepat tentang stack.
Mengapa kita perlu menempatkan anggota pribadi di header?
Tetapi apakah ada alasan untuk mendeklarasikan fungsi pribadi dalam definisi kelas?
Alternatif dasarnya adalah idiom jerawat tetapi tanpa tipuan berlebihan.
Apakah fitur bahasa ini lebih dari sekadar kesalahan historis?
Jika Anda membiarkan metode ditambahkan ke kelas di luar definisi, mereka dapat ditambahkan di mana saja , di file apa saja, oleh siapa saja.
Itu akan segera memberikan akses sepele kode klien ke anggota data pribadi dan terlindungi.
Setelah Anda menyelesaikan definisi kelas, tidak ada cara untuk menandai beberapa file sebagai diberkati secara khusus oleh penulis untuk memperluasnya - hanya ada unit terjemahan datar. Jadi, satu-satunya cara yang masuk akal untuk memberitahu kompiler bahwa serangkaian metode tertentu adalah resmi, atau diberkati oleh penulis kelas, adalah dengan mendeklarasikannya di dalam kelas.
Perhatikan bahwa kami memiliki akses langsung ke memori dalam C ++, yang berarti umumnya sepele untuk membuat tipe bayangan dengan tata letak memori yang sama dengan kelas Anda, tambahkan metode saya sendiri (atau buat semua data publik), dan
reinterpret_cast
. Atau saya dapat menemukan kode fungsi pribadi Anda, atau membongkarnya. Atau cari alamat fungsi di tabel simbol dan panggil atau langsung.Penentu akses ini tidak mencoba mencegah serangan ini, karena itu tidak mungkin. Mereka hanya menunjukkan bagaimana suatu kelas seharusnya digunakan.
sumber
Jawaban yang diterima menjelaskan hal ini untuk fungsi pribadi virtual , tetapi itu hanya menjawab satu sisi khusus dari pertanyaan, yang jauh lebih terbatas daripada apa yang ditanyakan OP. Jadi, kita perlu ulang: mengapa kita harus mendeklarasikan fungsi pribadi non-virtual di header?
Jawaban lain menunjukkan fakta bahwa kelas harus dideklarasikan dalam satu blok - setelah itu mereka disegel dan tidak dapat ditambahkan. Itulah yang akan Anda lakukan dengan menghilangkan untuk mendeklarasikan metode pribadi di header lalu mencoba mendefinisikannya di tempat lain. Poin yang bagus. Mengapa beberapa pengguna kelas dapat memperbanyaknya dengan cara yang tidak bisa diamati oleh pengguna lain? Metode pribadi adalah bagian dari itu dan tidak dikecualikan dari ini. Tapi kemudian Anda bertanya mengapa mereka termasuk, dan tampaknya agak tautologis. Mengapa pengguna kelas harus tahu tentang mereka? Jika tidak terlihat, pengguna tidak dapat menambahkan, dan hei presto.
Jadi, saya ingin memberikan jawaban bahwa, alih-alih hanya memasukkan metode pribadi secara default, memberikan poin tertentu agar dapat dilihat oleh pengguna. Alasan mekanistik untuk fungsi pribadi non-virtual yang membutuhkan deklarasi publik diberikan dalam GotW # 100 Herb Sutter tentang idiom Pimpl sebagai bagian dari alasannya. Saya tidak akan melanjutkan tentang Pimpl di sini, karena saya yakin kita semua tahu tentang itu. Tapi inilah bagian yang relevan:
Sutter tentu saja merupakan sumber yang sangat andal sebagai anggota Komite, jadi dia tahu "keputusan desain yang disengaja" ketika dia melihatnya. Dan gagasan untuk mewajibkan deklarasi publik tentang metode pribadi sebagai cara untuk menghindari perubahan semantik atau aksesibilitas yang tidak disengaja nantinya mungkin merupakan alasan yang paling meyakinkan. Syukurlah, karena semuanya tampak tidak berguna sebelumnya sekarang!
sumber
Ada dua alasan untuk melakukan ini.
Pertama, sadari bahwa specifier akses adalah untuk kompiler , dan tidak relevan saat runtime. Mengakses anggota pribadi di luar ruang lingkup adalah kesalahan kompilasi .
Keringkasan yg padat isinya
Pertimbangkan fungsi yang pendek, satu atau dua baris. Itu ada untuk mengurangi replikasi kode di tempat lain, yang juga memiliki keuntungan karena dapat mengubah cara suatu algoritma atau apa pun yang bekerja di satu tempat, bukan banyak (misalnya mengubah algoritma penyortiran).
Apakah Anda lebih suka memiliki satu atau dua baris cepat di header, atau memiliki prototipe fungsi di sana plus implementasi di suatu tempat? Lebih mudah ditemukan di header, dan untuk fungsi pendek, jauh lebih tepat untuk memiliki implementasi terpisah.
Ada keuntungan besar lainnya, yaitu ...
Fungsi sebaris
Fungsi pribadi mungkin dapat digarisbawahi, dan ini mengharuskannya berada di header. Pertimbangkan ini:
Fungsi pribadi mungkin dapat digarisbawahi bersama dengan fungsi publik. Itu dilakukan atas kebijakan kompiler, karena
inline
kata kunci secara teknis merupakan saran , bukan keharusan.sumber
inline
, tidak ada alasan untuk menggunakan kata kunci di sana..cpp
file yang diuraikan oleh fungsi anggota yang didefinisikan di luar definisi kelas, tetapi fungsi seperti itu tidak akan bersifat pribadi.Alasan lain untuk memiliki metode pribadi dalam file header: Ada kasus di mana metode inline publik tidak lebih dari memanggil satu atau beberapa metode pribadi. Memiliki metode pribadi di header berarti bahwa panggilan ke metode publik dapat sepenuhnya diuraikan ke kode sebenarnya dari metode pribadi, dan inlining tidak berhenti dengan panggilan ke metode pribadi. Bahkan dari unit kompilasi yang berbeda (dan metode publik biasanya dipanggil dari unit kompilasi yang berbeda).
Tentu saja ada alasannya juga bahwa kompiler tidak dapat mendeteksi masalah dengan resolusi kelebihan jika tidak mengetahui semua metode, termasuk yang pribadi.
sumber
Ini untuk memungkinkan fungsi-fungsi itu untuk mengakses anggota pribadi. Kalau tidak, Anda akan membutuhkannya
friend
di tajuk.Jika ada fungsi yang bisa mengakses anggota pribadi kelas maka pribadi tidak akan berguna.
sumber