Apa yang dilakukan makro Q_OBJECT? Mengapa semua objek Qt membutuhkan makro ini?
131
Saya baru saja mulai menggunakan Qt dan memperhatikan bahwa semua definisi kelas contoh memiliki makro Q_OBJECTsebagai baris pertama. Apa tujuan makro preprosesor ini?
Meta-Object Compiler, moc, adalah program yang menangani ekstensi Q ++ Ct.
Alat moc membaca file header C ++. Jika ia menemukan satu atau beberapa deklarasi kelas yang berisi makro Q_OBJECT, itu menghasilkan file sumber C ++ yang berisi kode objek-meta untuk kelas-kelas tersebut. Antara lain, kode objek-meta diperlukan untuk mekanisme sinyal dan slot, informasi tipe run-time, dan sistem properti dinamis.
mengapa saya tidak perlu menulis secara eksplisit Q_OBJECT::connect()tetapi lebih adil connect()?
mLstudent33
19
Ini hanya memberitahu pra-kompiler bahwa kelas ini memiliki elemen gui dan perlu dijalankan melalui 'moc' Anda hanya perlu menambahkan ini ke kelas yang menggunakan mekanisme sinyal / slot.
Tapi itu akan diabaikan dengan tenang di kelas lain - itu hanya menambah waktu membangun.
Ini juga salah bahwa Anda hanya membutuhkannya di kelas yang menggunakan mekanisme sinyal / slot. Tidak adanya Q_OBJECTistirahat qobject_castdan introspeksi. Ini dapat menyebabkan beberapa perilaku membingungkan, jadi itu ide yang buruk.
Pasang kembali Monica
2
Tidak benar bahwa Q_OBJECTakan "diam-diam" diabaikan di QObjectkelas (non- ) lainnya. Menurut standar C ++, ini memperkenalkan perilaku yang tidak terdefinisi dengan mendeklarasikan beberapa fungsi anggota dan variabel yang tidak pernah didefinisikan. Itu juga mencemari namespace kelas Anda dengan QObjectanggota -specific. Misalnya a Q_OBJECTdapat memecah kelas yang tidak terkait yang kebetulan mengandung metode yang disebut metaObject.
Pasang kembali Monica
2
Itu salah. Meskipun Anda mungkin ingin melengkapi sebagian besar kelas gui dengan Q_OBJECTmakro, masuk akal untuk memiliki kelas non-gui dengan makro, serta kelas gui tanpa makro. Makro berguna, tetapi tidak terbatas pada atau diperlukan untuk kelas gui.
pasbi
9
MOC (compiler objek meta) mengkonversi makro Q_OBJECT termasuk file header ke kode sumber setara C ++. Ini pada dasarnya mengontrol mekanisme slot sinyal, dan membuatnya dapat dimengerti oleh kompiler C ++
Itu salah: Q_OBJECTmakro diperluas oleh kompiler, moc tidak diperlukan untuk itu. MSC tidak melakukan apa pun dengan makro itu sendiri, tetapi ia menghasilkan definisi variabel anggota dan metode yang Q_OBJECTtelah dinyatakan makro .
Alat moc membaca file sumber C ++. Jika ia menemukan satu atau beberapa deklarasi kelas yang berisi makro Q_OBJECT, itu menghasilkan file sumber C ++ lain yang berisi kode objek-meta untuk masing-masing kelas tersebut. File sumber yang dihasilkan ini # dimasukkan ke dalam file sumber kelas atau, lebih biasanya, dikompilasi dan dihubungkan dengan implementasi kelas.
Makro Q_OBJECT harus muncul di bagian pribadi dari definisi kelas yang menyatakan sinyal dan slotnya sendiri atau yang menggunakan layanan lain yang disediakan oleh sistem objek-metrik Qt.
Alat moc membaca file header C ++. Jika ia menemukan satu atau beberapa deklarasi kelas yang berisi makro Q_OBJECT, itu menghasilkan file sumber C ++ yang berisi kode objek-meta untuk kelas-kelas tersebut. Antara lain, kode objek-meta diperlukan untuk mekanisme sinyal dan slot, informasi tipe run-time, dan sistem properti dinamis.
Makro Q_OBJECT diperluas oleh preprocessor untuk mendeklarasikan beberapa fungsi anggota yang diimplementasikan oleh moc; jika Anda mendapatkan kesalahan kompiler di sepanjang baris "referensi tidak terdefinisi ke vtable untuk LcdNumber", Anda mungkin lupa untuk menjalankan moc atau untuk memasukkan output moc dalam perintah tautan.
Dalam gcc dengan -EAnda dapat melihat makro diperluas. Inilah yang Q_OBJECTberkembang ke gcc di Linux. Ketahuilah, ini mungkin bergantung pada platform dan mungkin berubah tergantung pada versi QT. Anda dapat melihatnya bukan hanya tag untuk kompiler moc.
Makro Q_OBJECT harus muncul di bagian pribadi dari definisi kelas yang menyatakan sinyal dan slotnya sendiri atau yang menggunakan layanan lain yang disediakan oleh sistem objek-metrik Qt.
Ini menyesatkan: Q_OBJECTMakro harus muncul di setiap kelas yang berasal dari QObject. Kode Anda akan rusak secara halus ketika makro tidak ada, dan hanya karena kompilasi yang terjadi tidak membuatnya OK.
Pasang kembali Monica
@KubaOber apakah Anda memiliki contoh kode yang mengkompilasi tetapi tidak berfungsi ketika Q_OBJECTmakro hilang?
Chris
2
Jika Anda melihat implementasi Q_OBJECT , Anda akan menemukan bahwa itu menggunakan penentu akses. Jadi apakah makro akan muncul di bawah private, protectedatau publicspecifier tidak relevan - itu hanya konvensi untuk menempatkannya di kepala kelas.
Jawaban:
Dari dokumentasi Qt :
sumber
Q_OBJECT::connect()
tetapi lebih adilconnect()
?Ini hanya memberitahu pra-kompiler bahwa kelas ini memiliki elemen gui dan perlu dijalankan melalui 'moc' Anda hanya perlu menambahkan ini ke kelas yang menggunakan mekanisme sinyal / slot.
Tapi itu akan diabaikan dengan tenang di kelas lain - itu hanya menambah waktu membangun.
sumber
Q_OBJECT
istirahatqobject_cast
dan introspeksi. Ini dapat menyebabkan beberapa perilaku membingungkan, jadi itu ide yang buruk.Q_OBJECT
akan "diam-diam" diabaikan diQObject
kelas (non- ) lainnya. Menurut standar C ++, ini memperkenalkan perilaku yang tidak terdefinisi dengan mendeklarasikan beberapa fungsi anggota dan variabel yang tidak pernah didefinisikan. Itu juga mencemari namespace kelas Anda denganQObject
anggota -specific. Misalnya aQ_OBJECT
dapat memecah kelas yang tidak terkait yang kebetulan mengandung metode yang disebutmetaObject
.Q_OBJECT
makro, masuk akal untuk memiliki kelas non-gui dengan makro, serta kelas gui tanpa makro. Makro berguna, tetapi tidak terbatas pada atau diperlukan untuk kelas gui.MOC (compiler objek meta) mengkonversi makro Q_OBJECT termasuk file header ke kode sumber setara C ++. Ini pada dasarnya mengontrol mekanisme slot sinyal, dan membuatnya dapat dimengerti oleh kompiler C ++
sumber
Q_OBJECT
makro diperluas oleh kompiler, moc tidak diperlukan untuk itu. MSC tidak melakukan apa pun dengan makro itu sendiri, tetapi ia menghasilkan definisi variabel anggota dan metode yangQ_OBJECT
telah dinyatakan makro .1 Dari dokumentasi Qt The Meta-Object System
Alat moc membaca file sumber C ++. Jika ia menemukan satu atau beberapa deklarasi kelas yang berisi makro Q_OBJECT, itu menghasilkan file sumber C ++ lain yang berisi kode objek-meta untuk masing-masing kelas tersebut. File sumber yang dihasilkan ini # dimasukkan ke dalam file sumber kelas atau, lebih biasanya, dikompilasi dan dihubungkan dengan implementasi kelas.
2 Dari dokumentasi Qt THE Q_OBJECT
Makro Q_OBJECT harus muncul di bagian pribadi dari definisi kelas yang menyatakan sinyal dan slotnya sendiri atau yang menggunakan layanan lain yang disediakan oleh sistem objek-metrik Qt.
3 Dari dokumentasi Qt moc
Alat moc membaca file header C ++. Jika ia menemukan satu atau beberapa deklarasi kelas yang berisi makro Q_OBJECT, itu menghasilkan file sumber C ++ yang berisi kode objek-meta untuk kelas-kelas tersebut. Antara lain, kode objek-meta diperlukan untuk mekanisme sinyal dan slot, informasi tipe run-time, dan sistem properti dinamis.
4 Dari dokumentasi Qt untuk Sinyal dan Slot
Makro Q_OBJECT diperluas oleh preprocessor untuk mendeklarasikan beberapa fungsi anggota yang diimplementasikan oleh moc; jika Anda mendapatkan kesalahan kompiler di sepanjang baris "referensi tidak terdefinisi ke vtable untuk LcdNumber", Anda mungkin lupa untuk menjalankan moc atau untuk memasukkan output moc dalam perintah tautan.
sumber
Dalam gcc dengan
-E
Anda dapat melihat makro diperluas. Inilah yangQ_OBJECT
berkembang ke gcc di Linux. Ketahuilah, ini mungkin bergantung pada platform dan mungkin berubah tergantung pada versi QT. Anda dapat melihatnya bukan hanya tag untuk kompiler moc.sumber
Makro Q_OBJECT harus muncul di bagian pribadi dari definisi kelas yang menyatakan sinyal dan slotnya sendiri atau yang menggunakan layanan lain yang disediakan oleh sistem objek-metrik Qt.
sumber
Q_OBJECT
Makro harus muncul di setiap kelas yang berasal dariQObject
. Kode Anda akan rusak secara halus ketika makro tidak ada, dan hanya karena kompilasi yang terjadi tidak membuatnya OK.Q_OBJECT
makro hilang?Q_OBJECT
, Anda akan menemukan bahwa itu menggunakan penentu akses. Jadi apakah makro akan muncul di bawahprivate
,protected
ataupublic
specifier tidak relevan - itu hanya konvensi untuk menempatkannya di kepala kelas.