Saya telah belajar bahwa saya tidak pernah dapat mengakses variabel privat, hanya dengan fungsi get di kelas. Tetapi mengapa saya dapat mengaksesnya di konstruktor salinan?
Contoh:
Field::Field(const Field& f)
{
pFirst = new T[f.capacity()];
pLast = pFirst + (f.pLast - f.pFirst);
pEnd = pFirst + (f.pEnd - f.pFirst);
std::copy(f.pFirst, f.pLast, pFirst);
}
Deklarasi saya:
private:
T *pFirst,*pLast,*pEnd;
c++
private
access-specifier
demonking
sumber
sumber
const&
pengambil publik atau berdasarkan nilai untuk masing-masing? Maka mereka hanya 'tulis-pribadi', & untuk nilai-nilai menyia-nyiakan sumber daya & gagal untuk anggota yang tidak dapat disalin.) Saya bingung dengan keberhasilan pertanyaan hampa seperti itu, menanyakan tentang konstruksi-salinan sementara sama sekali mengabaikan artinya, & tidak ada jawaban yang menggunakan logika dasar untuk menyanggahnya. Mereka menjelaskan teknis kering, tetapi ada jawaban yang jauh lebih sederhana untuk pertanyaan yang berkedip iniJawaban:
IMHO, jawaban yang ada melakukan pekerjaan yang buruk menjelaskan "Mengapa" ini - terlalu berfokus pada mengulangi perilaku apa yang valid. "pengubah akses bekerja pada tingkat kelas, dan bukan pada tingkat objek." - iya tapi kenapa?
Konsep menyeluruh di sini adalah bahwa programmer merancang, menulis dan memelihara kelas yang diharapkan untuk memahami enkapsulasi OO yang diinginkan dan diberdayakan untuk mengoordinasikan implementasinya. Jadi, jika Anda menulis
class X
, Anda menyandikan tidak hanya bagaimana sebuahX x
objek dapat digunakan oleh kode yang memiliki akses ke sana, tetapi juga bagaimana:X
objek yang berbeda bekerja sama untuk memberikan perilaku yang dimaksudkan sambil menghormati kondisi pasca dan invarian dari desain Anda.Ini bukan hanya konstruktor salinan - banyak sekali operasi yang dapat melibatkan dua atau lebih contoh kelas Anda: jika Anda membandingkan, menambah / mengalikan / membagi, menyalin-membangun, mengkloning, menetapkan, dll. Maka sering kali Anda baik hanya harus memiliki akses ke data pribadi dan / atau dilindungi di objek lain, atau ingin memungkinkan implementasi fungsi yang lebih sederhana, lebih cepat, atau secara umum lebih baik.
Secara khusus, operasi ini mungkin ingin memanfaatkan akses pribadi untuk melakukan hal-hal seperti:
shared_ptr
ke data referensi, dll.auto_ptr<>
"memindahkan" kepemilikan ke objek yang sedang dibangununordered_map
anggota tetapi secara publik hanya mengeksposbegin()
danend()
iterator - dengan akses langsung kesize()
Anda dapatreserve
kapasitas untuk menyalin lebih cepat; lebih buruk lagi jika mereka hanya mengeksposat()
daninsert()
dan sebaliknyathrow
....sumber
this == other
setiap kali Anda mengaksesother.x
yang harus Anda lakukan jika pengubah akses bekerja pada tingkat objek.this == other
setiap kali Anda mengaksesother.x
" - meleset dari intinya - jikaother.x
hanya diterima pada waktu proses jika setara denganthis.x
, tidak akan ada banyak penulisan pointerother.x
di tempat pertama; kompiler mungkin juga memaksa Anda untuk menulisif (this == other) ...this.x...
apa pun yang akan Anda lakukan. Anda "kenyamanan (bahkan lebih jika variabel swasta publik)" konsepsi juga melenceng - cara didefinisikan cukup ketat Standar untuk memungkinkan tepat enkapsulasi, tetapi tidak perlu merepotkan.Pengubah akses bekerja pada tingkat kelas , dan bukan pada tingkat objek .
Artinya, dua objek dari kelas yang sama dapat mengakses data pribadi satu sama lain.
Mengapa:
Terutama karena efisiensi. Ini akan menjadi overhead
this == other
waktu proses yang tidak dapat diabaikan untuk memeriksa apakah setiap kali Anda mengaksesother.x
yang harus Anda lakukan jika pengubah akses bekerja pada tingkat objek.Ini juga agak logis secara semantik jika Anda memikirkannya dalam istilah pelingkupan: "Seberapa besar bagian kode yang perlu saya ingat saat memodifikasi variabel privat?" - Anda perlu mengingat kode seluruh kelas, dan ini ortogonal objek yang ada saat runtime.
Dan sangat nyaman saat menulis pembuat salinan dan operator penugasan.
sumber
Anda dapat mengakses anggota privat kelas dari dalam kelas tersebut, bahkan dari instance lain.
sumber
Untuk memahami jawabannya, saya ingin mengingatkan Anda beberapa konsep.
this
pointer diteruskan ke setiap fungsi saat dipanggil.Sekarang karena
this
penunjuknya, fungsi dapat menemukan variabel dari contoh tertentu itu. tidak peduli apakah itu pribadi untuk umum. itu dapat diakses di dalam fungsi itu. Sekarang jika kita meneruskan pointer ke objek lain dari kelas yang sama. menggunakan penunjuk kedua ini kita akan dapat mengakses anggota pribadi.Semoga ini menjawab pertanyaan Anda.
sumber
Copy konstruktor adalah fungsi anggota kelas dan dengan demikian memiliki akses ke anggota data kelas, bahkan yang dideklarasikan sebagai 'pribadi'.
sumber