मैंने सिर्फ क्यूटी का उपयोग करना शुरू किया और देखा कि सभी उदाहरण वर्ग परिभाषाओं Q_OBJECT
में पहली पंक्ति के रूप में मैक्रो है । इस प्रीप्रोसेसर मैक्रो का उद्देश्य क्या है?
मैंने सिर्फ क्यूटी का उपयोग करना शुरू किया और देखा कि सभी उदाहरण वर्ग परिभाषाओं Q_OBJECT
में पहली पंक्ति के रूप में मैक्रो है । इस प्रीप्रोसेसर मैक्रो का उद्देश्य क्या है?
जवाबों:
से क्यूटी प्रलेखन :
मेटा-ऑब्जेक्ट कंपाइलर, moc, वह प्रोग्राम है जो Qt के C ++ एक्सटेंशन को हैंडल करता है।
Moc टूल एक C ++ हैडर फ़ाइल पढ़ता है। यदि यह Q_OBJECT मैक्रो वाले एक या अधिक श्रेणी की घोषणाएँ पाता है, तो यह उन वर्गों के लिए मेटा-ऑब्जेक्ट कोड वाले C ++ स्रोत फ़ाइल का उत्पादन करता है। अन्य बातों के अलावा, संकेत और स्लॉट तंत्र, रन-टाइम प्रकार की जानकारी और गतिशील संपत्ति प्रणाली के लिए मेटा-ऑब्जेक्ट कोड आवश्यक है।
Q_OBJECT::connect()
, बल्कि सिर्फ लिखने की connect()
?
यह केवल पूर्व-संकलक को बताता है कि इस वर्ग में गुई तत्व हैं और इसे 'मॉक' के माध्यम से चलाने की आवश्यकता है जो आपको केवल उन कक्षाओं में जोड़ना होगा जो सिग्नल / स्लॉट तंत्र का उपयोग करते हैं।
लेकिन इसे चुपचाप किसी भी अन्य वर्गों में नजरअंदाज कर दिया जाएगा - यह सिर्फ निर्माण समय में जोड़ता है।
Q_OBJECT
टूट जाता है qobject_cast
और आत्मनिरीक्षण। यह कुछ खराब व्यवहार को जन्म दे सकता है, इसलिए यह एक बुरा विचार है।
Q_OBJECT
किसी अन्य (गैर- QObject
) कक्षाओं में "चुपचाप" अनदेखा किया जाएगा । सी ++ मानक के अनुसार, यह कई सदस्य कार्यों और चर की घोषणा करके अपरिभाषित व्यवहार का परिचय देता है जो कभी भी परिभाषित नहीं होते हैं। यह आपके वर्ग के नाम स्थान को- QObject
सदस्यों के साथ प्रदूषित भी करता है । उदाहरण के लिए, एक Q_OBJECT
असंबंधित वर्ग को अच्छी तरह से तोड़ सकता है जिसमें एक विधि होती है जिसे कहा जाता है metaObject
।
Q_OBJECT
मैक्रो से लैस करना चाहते हैं , लेकिन यह मैक्रो के साथ गैर-गिनी-कक्षाओं के साथ-साथ मैक्रो के बिना भी गिनी-कक्षाओं के लिए पूरी तरह से समझ में आता है। मैक्रो उपयोगी है, लेकिन न तो गिनी-कक्षाओं के लिए आवश्यक है और न ही सीमित है।
MOC (मेटा ऑब्जेक्ट कंपाइलर) Q_OBJECT मैक्रो में शामिल हेडर फ़ाइलों को C ++ समतुल्य स्रोत कोड में परिवर्तित करता है। यह मूल रूप से सिग्नल-स्लॉट तंत्र को नियंत्रित करता है, और इसे C ++ कंपाइलर के लिए समझ में आता है
Q_OBJECT
मैक्रो कंपाइलर द्वारा विस्तारित है, इसके लिए मॉक की आवश्यकता नहीं है। मॉक मैक्रो के साथ कुछ भी नहीं करता है, लेकिन यह सदस्य चर और विधियों की परिभाषाएं उत्पन्न करता है जो Q_OBJECT
मैक्रो ने घोषित किया है ।
1 मेटा-ऑब्जेक्ट सिस्टम के क्यूटी प्रलेखन से
Moc टूल एक C ++ सोर्स फाइल पढ़ता है। यदि यह Q_OBJECT मैक्रो वाले एक या अधिक श्रेणी की घोषणाएँ पाता है, तो यह एक और C ++ स्रोत फ़ाइल बनाता है जिसमें उन प्रत्येक वर्गों के लिए मेटा-ऑब्जेक्ट कोड होता है। यह जेनरेट की गई सोर्स फाइल या तो # क्लास के सोर्स फाइल में शामिल है या, आमतौर पर, क्लास के कार्यान्वयन के साथ संकलित और लिंक की जाती है।
2 Q_OBJECT के क्यूटी प्रलेखन से
Q_OBJECT मैक्रो को एक वर्ग परिभाषा के निजी अनुभाग में दिखाई देना चाहिए जो अपने स्वयं के संकेतों और स्लॉट की घोषणा करता है या जो Qt की मेटा-ऑब्जेक्ट सिस्टम द्वारा प्रदान की गई अन्य सेवाओं का उपयोग करता है।
3 मॉक के क्यूटी प्रलेखन से
Moc टूल एक C ++ हैडर फ़ाइल पढ़ता है। यदि यह Q_OBJECT मैक्रो वाले एक या अधिक श्रेणी की घोषणाएँ पाता है, तो यह उन वर्गों के लिए मेटा-ऑब्जेक्ट कोड वाले C ++ स्रोत फ़ाइल का उत्पादन करता है। अन्य बातों के अलावा, संकेत और स्लॉट तंत्र, रन-टाइम प्रकार की जानकारी और गतिशील संपत्ति प्रणाली के लिए मेटा-ऑब्जेक्ट कोड आवश्यक है।
4 सिग्नल और स्लॉट के क्यूटी प्रलेखन से
Q_OBJECT मैक्रो को कई सदस्य कार्यों को घोषित करने के लिए प्रीप्रोसेसर द्वारा विस्तारित किया जाता है जो कि मॉक द्वारा कार्यान्वित किए जाते हैं; यदि आपको "LcdNumber के लिए अपरिहार्य संदर्भ" की पंक्तियों के साथ कंपाइलर त्रुटियां मिलती हैं, तो आप संभवतः moc को रन करना या लिंक कमांड में moc आउटपुट को शामिल करना भूल गए हैं।
जीसीसी में -E
आप विस्तारित मैक्रोज़ देख सकते हैं। यह वही है जो Q_OBJECT
लिनक्स पर gcc में विस्तार करता है। जागरूक रहें, यह प्लेटफॉर्म पर निर्भर हो सकता है और यह क्यूटी के संस्करण के आधार पर बदल सकता है। आप देख सकते हैं कि यह मॉक कंपाइलर के लिए केवल एक टैग नहीं है।
# 11 "mainwindow.hh"
#pragma GCC diagnostic push
# 11 "mainwindow.hh"
# 11 "mainwindow.hh"
#pragma GCC diagnostic ignored "-Wsuggest-override"
# 11 "mainwindow.hh"
static const QMetaObject staticMetaObject; virtual const QMetaObject *metaObject() const; virtual void *qt_metacast(const char *); virtual int qt_metacall(QMetaObject::Call, int, void **); static inline QString tr(const char *s, cons
t char *c = nullptr, int n = -1) { return staticMetaObject.tr(s, c, n); } __attribute__ ((__deprecated__)) static inline QString trUtf8(const char *s, const char *c = nullptr, int n = -1) { return staticMetaObject.tr(s, c, n); } private:
# 11 "mainwindow.hh"
#pragma GCC diagnostic ignored "-Wattributes"
# 11 "mainwindow.hh"
__attribute__((visibility("hidden"))) static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **);
# 11 "mainwindow.hh"
#pragma GCC diagnostic pop
# 11 "mainwindow.hh"
struct QPrivateSignal {};
Q_OBJECT मैक्रो को एक वर्ग परिभाषा के निजी अनुभाग में दिखाई देना चाहिए जो अपने स्वयं के संकेतों और स्लॉट की घोषणा करता है या जो Qt की मेटा-ऑब्जेक्ट सिस्टम द्वारा प्रदान की गई अन्य सेवाओं का उपयोग करता है।
Q_OBJECT
मैक्रो को हर उस वर्ग में प्रकट होना चाहिए जो इससे प्राप्त होता है QObject
। मैक्रो अनुपस्थित होने पर आपका कोड आसानी से टूट जाएगा, और क्योंकि यह संकलन करने के लिए होता है यह ठीक नहीं है।
Q_OBJECT
मैक्रो के लापता होने पर काम नहीं करता है?
Q_OBJECT
, तो आप पाएंगे कि यह एक्सेस स्पेसियर्स का उपयोग करता है। इसलिए चाहे मैक्रो के तहत में दिखाई देनी चाहिए private
, protected
या public
विनिर्देशक अप्रासंगिक है - यह वर्ग के सिर पर यह जगह करने के लिए सिर्फ सम्मेलन है।