मैं भविष्य में क्यूटी 5.9 के तहत विकसित किए गए विगेट्स की लाइब्रेरी संभव बनाने के बारे में चिंतित हूं, जो भविष्य में इसे पहले से उपयोग किए जाने वाले कोड को दोबारा उपयोग किए बिना अपग्रेड किया जा सकता है। बेशक मैं pimpl मुहावरा के साथ शुरू कर दिया है और इसके बारे में Qt संस्करण here और here का वर्णन किया।क्यूटी में स्लॉट के रूप में सी ++ लैम्ब्डा फ़ंक्शंस का उपयोग करना लाइब्रेरी की बाइनरी संगतता को संरक्षित रखने में मदद करता है?
हालांकि मेरे कोड को अनुकूलित करने का प्रयास करते समय, मैं इस विचार के साथ आया कि नए डेटा सदस्यों को जोड़ने और उन्हें एक अलग निजी वर्ग में स्थानांतरित करने के बजाय, मैं कंब के सिग्नल/स्लॉट तंत्र का उपयोग लैम्ब्डा कार्यों के साथ कर सकता हूं और केवल स्थानीय चर
संस्करण एक::
class Foo : public QWidget
{
Q_OBJECT
public:
explicit Foo(QWidget *parent = nullptr);
private:
// A bunch of data members
QPushButton *m_button;
QLineEdit *m_lineEdit;
QCheckBox *m_checkBox;
QString m_str;
private slots:
void on_pushButtonClicked();
void on_checkBoxStateChanged(int state);
};
Foo::Foo(QWidget *parent) :
QWidget(parent),
m_button(new QPushButton("Click me", this));
m_lineEdit(new QLineEdit(this)),
m_checkBox(new QCheckBox(this)),
m_str("Initial text")
{
connect(button, &QPushButton::clicked, this, &Foo::on_pushButtonClicked);
connect(checkBox, &QCheckBox::stateChanged, this, &Foo::on_checkBoxStateChanged);
}
Foo::on_pushButtonClicked()
{
m_str = m_lineEdit->text();
m_lineEdit->setDisabled(m_checkBox->isChecked());
}
Foo::on_checkBoxStateChanged(int state)
{
m_button->setText(state == Qt::Checked ? m_str : "Click me")
}
संस्करण बी: के निम्न उदाहरण के साथ विचार को वर्णन करते संस्करण बी के लिए
class Foo : public QWidget
{
Q_OBJECT
public:
explicit Foo(QWidget *parent = nullptr);
};
Foo::Foo(QWidget *parent) : QWidget(parent)
{
QPushButton *button = new QPushButton("Click me", this);
QLineEdit *lineEdit = new QLineEdit(this);
QCheckBox *checkBox = new QCheckBox(this);
QString str("Initial text");
connect(button, &QPushButton::clicked, [=](){
str = lineEdit->text();
lineEdit->setDisabled(checkBox->isChecked());
});
connect(checkBox, &QCheckBox::stateChanged, [=](int state){
button->setText(state == Qt::Checked ? str : "Click me")
});
}
तो, - अलग अधिक कॉम्पैक्ट होने से , इसमें कोई क्लास डेटा सदस्य नहीं है, इसलिए छिपाने के लिए कोई चर नहीं है, इसलिए डी-पॉइंटर की आवश्यकता नहीं है। बाइनरी संगतता अभी भी गारंटीकृत है (या यह है?), अगर भविष्य में कन्स्ट्रक्टर को उसी सिग्नल/स्लॉट तरीके से उपयोग किए गए अतिरिक्त स्थानीय चर के साथ पुन: कार्यान्वित किया जाता है। क्या मुझे लगता है कि यह काम करेगा या ऐसा दृष्टिकोण चाल नहीं करेगा?
नोट: lambdas का उपयोग कर के रूप में क्यूटी में स्लॉट @Igor Tandetnik here द्वारा टिप्पणी की जांच के बारे में अधिक जानकारी के लिए।
मुझे नहीं लगता कि संकलन करेंगे। लैम्बडा के अंदर 'str' होगा। यहां तक कि यदि यह संकलित करता है, तो ध्यान दें कि आप मूल्य से कैप्चर करते हैं: उन दो अलग-अलग लैम्बडा में 'str' अलग-अलग, स्वतंत्र वस्तुओं को संदर्भित करता है। आपको एक हीप-आवंटित सूचक द्वारा सब कुछ पकड़ना होगा - स्टेरॉयड पर एक 'पिंपल'। –
@IgorTandetnik, मुझे आपका अंक मिला है। हालांकि, इस कन्स्ट्रक्टर के एकमात्र पुनर्मूल्यांकन को बाइनरी संगतता को तोड़ना नहीं चाहिए, क्या इसे चाहिए? – scopchanov
मुझे यकीन नहीं है कि आपका मतलब "बाइनरी संगतता" से क्या है। जब तक आप उस शीर्षक को संशोधित नहीं करते हैं जहां 'Foo' वर्ग परिभाषित किया गया है, तो आपको' Foo' का उपयोग करके स्रोतों को पुन: संकलित करने की आवश्यकता नहीं होगी, अगर आप यही पूछ रहे हैं। उस ने कहा, आपको Variant B. की शैली में कोड का कोई महत्वपूर्ण टुकड़ा लिखने में कठिनाई होगी। सामान्य कक्षा में, आप एक निजी सदस्य फ़ंक्शन कर सकते हैं जिसे आप एकाधिक स्थानों से कॉल कर सकते हैं। अब आप कोड का पुन: उपयोग करने की योजना कैसे बना रहे हैं? प्रत्येक "सदस्य फ़ंक्शन" के लिए कन्स्ट्रक्टर में लैम्ब्डा बनाएं, और क्या सभी कनेक्शन हैंडलर इसे कैप्चर करते हैं? यह बहुत तेज बहुत तेज हो जाएगा। –