Di C #, ada gula sintaks yang bagus untuk bidang dengan pengambil dan penyetel. Selain itu, saya menyukai properti yang diimplementasikan secara otomatis yang memungkinkan saya untuk menulis
public Foo foo { get; private set; }
Di C ++ saya harus menulis
private:
Foo foo;
public:
Foo getFoo() { return foo; }
Apakah ada beberapa konsep seperti itu di C ++ 11 yang memungkinkan saya memiliki beberapa gula sintaks dalam hal ini?
Jawaban:
Di C ++ Anda dapat menulis fitur Anda sendiri. Berikut adalah contoh implementasi properti menggunakan kelas tanpa nama. Artikel Wikipedia
Anda dapat menulis getter & setter Anda sendiri di tempatnya dan jika Anda ingin akses anggota kelas pemegang, Anda dapat memperluas kode contoh ini.
sumber
_alpha
variabel privat danalpha
untuk referensi.sizeof(Foo)
.C ++ tidak memiliki bawaan ini, Anda dapat menentukan template untuk meniru fungsionalitas properti:
Untuk mendefinisikan properti :
Untuk mengimplementasikan pengambil / penyetel khusus cukup mewarisi:
Untuk mendefinisikan properti read-only :
Dan untuk menggunakannya di kelas
Owner
:Anda dapat menentukan beberapa hal di atas dalam makro agar lebih ringkas.
sumber
virtual
adalah mungkin perlu untuk kebanyakan kasus penggunaan, sejak Properti tidak mungkin digunakan polymorphically.Tidak ada dalam bahasa C ++ yang akan berfungsi di semua platform dan kompiler.
Tetapi jika Anda ingin merusak kompatibilitas lintas platform dan berkomitmen untuk kompiler tertentu, Anda mungkin dapat menggunakan sintaks tersebut, misalnya di Microsoft Visual C ++ Anda dapat melakukannya
sumber
Anda dapat meniru pengambil dan penyetel sampai batas tertentu dengan memiliki anggota tipe khusus dan menimpa
operator(type)
danoperator=
untuk itu. Apakah itu ide yang bagus adalah pertanyaan lain dan saya akan+1
menjawab jawaban Kerrek SB untuk mengungkapkan pendapat saya atasnya :)sumber
friend
ke pemilik bidang.Mungkin lihatlah kelas properti yang telah saya kumpulkan selama beberapa jam terakhir: /codereview/7786/c11-feedback-on-my-approach-to-c-like-class-properties
Ini memungkinkan Anda memiliki properti yang berperilaku seperti ini:
sumber
Dengan C ++ 11 Anda dapat menentukan template kelas Properti dan menggunakannya seperti ini:
Dan inilah template kelas Property.
sumber
C::*
maksudnya Saya belum pernah melihat yang seperti ini sebelumnya?C
. Ini mirip dengan penunjuk fungsi biasa tetapi untuk memanggil fungsi anggota Anda perlu menyediakan objek tempat fungsi tersebut dipanggil. Ini dicapai dengan garisitsObject->*itsSetter(theValue)
pada contoh di atas. Lihat di sini untuk penjelasan lebih rinci tentang fitur ini.Seperti yang telah dikatakan banyak orang lain, tidak ada dukungan bawaan dalam bahasa tersebut. Namun, jika Anda menargetkan kompiler Microsoft C ++, Anda dapat memanfaatkan ekstensi khusus Microsoft untuk properti yang didokumentasikan di sini.
Ini adalah contoh dari halaman tertaut:
sumber
Tidak, C ++ tidak memiliki konsep properti. Meskipun sulit untuk mendefinisikan dan memanggil getThis () atau setThat (value), Anda membuat pernyataan kepada konsumen dari metode tersebut bahwa beberapa fungsionalitas dapat terjadi. Mengakses bidang di C ++, di sisi lain, memberi tahu konsumen bahwa tidak ada fungsionalitas tambahan atau tak terduga yang akan terjadi. Properti akan membuat hal ini kurang jelas karena akses properti pada pandangan pertama tampak bereaksi seperti bidang, tetapi pada kenyataannya bereaksi seperti metode.
Selain itu, saya bekerja di aplikasi .NET (CMS yang sangat terkenal) mencoba membuat sistem keanggotaan pelanggan. Karena cara mereka menggunakan properti untuk objek pengguna mereka, tindakan dijalankan yang tidak saya antisipasi, menyebabkan implementasi saya dieksekusi dengan cara yang aneh termasuk rekursi tak terbatas. Ini karena objek penggunanya melakukan panggilan ke lapisan akses data atau beberapa sistem cache global saat mencoba mengakses hal-hal sederhana seperti StreetAddress. Seluruh sistem mereka didasarkan pada apa yang saya sebut sebagai penyalahgunaan properti. Seandainya mereka menggunakan metode alih-alih properti, saya pikir saya akan lebih cepat mengetahui apa yang salah. Seandainya mereka telah menggunakan bidang (atau setidaknya membuat properti mereka berperilaku lebih seperti bidang), saya pikir sistem akan lebih mudah untuk diperluas dan dipelihara.
[Sunting] Mengubah pikiran saya. Aku mengalami hari yang buruk dan sedikit mengomel. Pembersihan ini harus lebih profesional.
sumber
Berdasarkan https://stackoverflow.com/a/23109533/404734, berikut adalah versi dengan pengambil publik dan penyetel pribadi:
sumber
Ini sebenarnya bukan properti, tetapi melakukan apa yang Anda inginkan dengan cara sederhana:
Di sini X besar berperilaku seperti
public int X { get; private set; }
dalam sintaks C #. Jika Anda menginginkan properti full-blown, saya membuat bidikan pertama untuk menerapkannya di sini .sumber
X
objek baru akan tetap mengarah ke anggota objek lama, karena hanya disalin seperti anggota penunjuk. Ini sendiri buruk, tetapi ketika objek lama dihapus, Anda mendapatkan kerusakan memori di atasnya. Untuk membuat ini bekerja, Anda juga harus menerapkan konstruktor salinan Anda sendiri, operator penugasan, dan memindahkan konstruktor.Anda mungkin tahu itu tetapi saya hanya akan melakukan hal berikut:
Pendekatan ini sederhana, tidak menggunakan trik cerdas dan menyelesaikan pekerjaan!
Masalahnya adalah bahwa beberapa orang tidak suka memberi awalan bidang pribadi mereka dengan garis bawah sehingga mereka tidak dapat benar-benar menggunakan pendekatan ini, tetapi untungnya bagi mereka yang melakukannya, ini sangat mudah. :)
Dapatkan dan setel prefiks tidak menambah kejelasan pada API Anda tetapi membuatnya lebih bertele-tele dan alasan saya rasa mereka tidak menambahkan informasi yang berguna adalah karena ketika seseorang perlu menggunakan API jika API masuk akal, dia mungkin akan menyadari apa itu tidak tanpa awalan.
Satu hal lagi, mudah untuk memahami bahwa ini adalah properti karena
name
bukan kata kerja.Skenario terburuk, jika API konsisten dan orang tersebut tidak menyadari bahwa itu
name()
adalah aksesor danname(value)
mutator maka dia hanya perlu mencarinya sekali dalam dokumentasi untuk memahami polanya.Sebanyak saya suka C # Saya rasa C ++ tidak membutuhkan properti sama sekali!
sumber
foo(bar)
(bukan yang lebih lambatfoo = bar
), tetapi pengakses Anda tidak ada hubungannya dengan properti sama sekali ...foo(bar)
alih - alihfoo=bar
yang dapat dicapai denganvoid foo(Bar bar)
metode mutator pada_foo
variabel anggota.Tidak .. Tetapi Anda harus mempertimbangkan jika hanya get: set function dan tidak ada tugas tambahan yang dibentuk sebelumnya di dalam get: set, buat saja menjadi publik.
sumber
Saya mengumpulkan ide-ide dari beberapa sumber C ++ dan memasukkannya ke dalam contoh yang bagus, masih cukup sederhana untuk getter / setter di C ++:
Keluaran:
Anda dapat mengujinya secara online di sini: http://codepad.org/zosxqjTX
sumber
Apakah kelas Anda benar-benar perlu memberlakukan beberapa invarian atau apakah itu hanya pengelompokan logis dari elemen anggota? Jika yang terakhir, Anda harus mempertimbangkan untuk membuat hal itu menjadi struct dan mengakses anggota secara langsung.
sumber
Ada satu set makro yang tertulis di sini . Ini memiliki deklarasi properti yang nyaman untuk tipe nilai, tipe referensi, tipe hanya baca, tipe kuat dan tipe lemah.
sumber