Da principiante a C++ qui. Stavo leggendo A Deeper Look at Signals and Slots, che afferma che 1) i callback sono intrinsecamente di tipo non sicuri e 2) per renderli sicuri è necessario definire un wrapper di classe virtuale puro attorno alla propria funzione. Ho difficoltà a capire perché è vero. A titolo di esempio, ecco il codice Qt fornisce sul proprio tutorial page for signals and slots:Perché i segnali e gli slot sono migliori di semplici vecchi callback?
// Header file
#include <QObject>
class Counter : public QObject
{
Q_OBJECT
public:
Counter() { m_value = 0; }
int value() const { return m_value; }
public slots:
void setValue(int value);
signals:
void valueChanged(int newValue);
private:
int m_value;
};
// .cpp file
void Counter::setValue(int value)
{
if (value != m_value) {
m_value = value;
emit valueChanged(value);
}
}
// Later on...
Counter a, b;
QObject::connect(&a, SIGNAL(valueChanged(int)),
&b, SLOT(setValue(int)));
a.setValue(12); // a.value() == 12, b.value() == 12
b.setValue(48); // a.value() == 12, b.value() == 48
qui è che il codice riscritto utilizzando le richiamate:
#include <functional>
#include <vector>
class Counter
{
public:
Counter() { m_value = 0; }
int value() const { return m_value; }
std::vector<std::function<void(int)>> valueChanged;
void setValue(int value);
private:
int m_value;
};
void Counter::setValue(int value)
{
if (value != m_value) {
m_value = value;
for (auto func : valueChanged) {
func(value);
}
}
}
// Later on...
Counter a, b;
auto lambda = [&](int value) { b.setValue(value); };
a.valueChanged.push_back(lambda);
a.setValue(12);
b.setValue(48);
Come si può vedere, la versione di callback è di tipo-sicuro e più breve rispetto alla versione Qt, despite them claiming that it's not. Non definisce nuove classi, a parte lo Counter
. Utilizza solo il codice della libreria standard e non ha bisogno di un compilatore speciale (moc) per funzionare. Perché, quindi, i segnali e le bande sono preferiti rispetto ai callback? Il C++ 11 ha semplicemente reso obsoleti questi concetti?
Grazie.
Qt è molto più vecchio di C++ 11. Le affermazioni contenute nella documentazione, nei white paper, ecc. Devono essere lette come affermazioni per "C++ come C migliore rispetto allo standard C++ 11". In particolare affermazioni sciocche come "i richiami hanno due difetti fondamentali: in primo luogo, non sono sicuri per il tipo". non ha senso per C++ come C++: per capirlo bisogna pensare in termini di pura programmazione in C. –
Non confondere "l'implementazione di Qt di segnali e slot" con "segnali e slot" il concetto. Quando qualcosa mantiene come lista di callback e li chiama tutti quando si verifica un evento. hai l'essenza di segnali e slot. Tutto il resto è zucchero, sintassi e marketing. Quello che hai è una multa, seppur semplicistica, implementazione di un sistema di segnale e di slot. – GManNickG
@GManNickG Allora qual è esattamente la differenza tra la mia implementazione e Qt? –