Qt “özel yuvalar:” bu nedir?


84

Nasıl kullanılacağını anlıyorum, ancak sözdizimi beni rahatsız ediyor. "Özel yuvalar" ne yapıyor?

Daha önce sınıf tanımında private anahtar kelimesi ile: arasında bir şey görmemiştim. Burada bazı süslü C ++ büyüsü var mı?

Ve burada örnek:

 #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);

 ...

3
Bu Standart C ++ değildir, Bu QT çerçeve yapısıdır. Arama QT sinyal ve yuva .
Alok Save

1
C ++ slotsolarak derlenirken #define slots. Qt MOC kullanarak derlerken, C ++ derleyicisi için kod üretir.
dalle

2
lol bunu anlamak benim için daha da zordu çünkü çok uzun süredir C ++ kullanmadım, yeni bir şey eklediklerini düşündüm
dtc

Yanıtlar:


57

Yuvalar, C ++ 'nın Qt'ye özgü bir uzantısıdır. Yalnızca kodu Qt'nin ön işlemcisi Meta Nesne Derleyicisi (moc) aracılığıyla gönderdikten sonra derler. Belgeler için http://doc.qt.io/qt-5/moc.html bakın .

Düzenleme: Frank'in işaret ettiği gibi, moc yalnızca bağlantı için gereklidir. Ekstra anahtar kelimeler standart önişlemci ile # tanımlanır.


Teşekkürler, Qt'nin ön işlemcisi, neler olduğuna dair zihinsel modelimde eksik olan şeydi.
Justin

16
Doğru değil, kod her zaman "sinyaller" ve "yuvalar" boş tanımlar olarak derlenir, böylece derleyici onları asla görmez. Bu makrolar, ek kod üreten moc için ipuçlarıdır . Orijinal .h ve .cpp dosyaları değiştirilmez ve moc olmadan gayet iyi derlenir. Aksi takdirde, moc tarafından üretilen tanımlar (sinyal tanımları, meta nesne, vb.) Eksik olduğu için başarısız olacak olan bağlantıdır.
Frank Osterfeld

1
slotsanahtar kelime gerekli? slotsAnahtar kelime olmadan slotları çağıran birkaç küçük Qt programını derlemeyi / bağlamayı denedim ve çok iyi inşa ettiler. Deneylerim gösteriyor ki: signals:kesinlikle gerekli, slotsgereksiz olabilir ve emitbaşka yerlerde okuduğum gibi gereksiz görünüyor.
It's Your App LLC

2
slotsQt5'te gerekli değildir. Qt connect(), lambdalar da dahil olmak üzere rastgele bir işleve bir sinyal bağlanmasına izin vermek için sözdizimini güncelledi . Bu nedenle slotsgerekli değildir. Ancak, slotsanahtar kelime hala bir nesnenin oluşturulma şeklini etkiler QMetaObject. moc(aka, "meta-nesne derleyicisi") slots:, bir sınıf tanımının bölümünde olmadığı sürece bir yöntemi yuva olarak tanımaz . Bu nedenle, bağlantı hala çalışacak olsa da, yöntem iç gözlem araçlarında görünmeyecektir.
Chris

19

public, Gibi anahtar sözcükler privateQt yuvaları için göz ardı edilir. Tüm yuvalar aslında herkese açıktır ve bağlanabilir


31
Yöntem sinyal / yuva mekanizması aracılığıyla çağrıldığında, erişim belirleyicileri göz ardı edilir. Ancak yuvalar aynı zamanda "normal" yöntemlerdir. Bunları geleneksel yolu kullanarak aradığınızda, erişim belirleyicileri dikkate alınır.
borges

4
@borges ve gelecekteki okuyucular. Qt5'te connect () yöntemi, (avantajları olan) işlev işaretçileri kullanabilir. İşlev işaretçileriyle bağlanırsanız, erişim belirticileri sinyaller / yuvalar mekanizmasında zorlanır.
Tod

3
@borges Bunun yanlış olduğuna inanıyorum ya da en azından açıklaması net değildi. Erişim belirteçleri, sinyalleri yuvalara bağlama becerinizi kısıtlamaz; yani özel bir yuva herhangi bir sinyale bağlanabilir . Bununla birlikte, erişim belirteci, çağrılırken üye işlevini kendi sınıfından (tipik şekilde) korur. Bu nedenle, erişim belirleyicileri sinyal / yuva mekanizması aracılığıyla çağrıldıklarında "göz ardı edilmez": yuvaları sinyallere bağlamayla ilgileri yoktur, ancak işlevi thisaşina olduğumuz şekilde korurlar .
It's Your App LLC

4

Yuvaları özel olarak ilan etmek, diğer yöntemler gibi, özel oldukları bağlamdan bunlara başvuramayacağınız anlamına gelir. Sonuç olarak, özel yuvaların adresini geçiremezsiniz connect.

Sinyali özel olarak bildirirseniz, yalnızca bu sınıfın onu yönetebileceğini, ancak işlev üye işaretçilerinin erişim kısıtlamaları olmadığını söylüyorsunuz :

class A{
    private:
    void e(){

    }
    public:
    auto getPointer(){
        return &A::e;   
    }
};

int main()
{
    A a;
    auto P=a.getPointer();
    (a.*P)();
}

Bunun dışında, başka cevaplar da geçerlidir:
- özel sinyalleri ve yuvaları dışarıdan hilelerle bağlayabilirsiniz
- signalsve slotsboş makrolardır ve dil standardını ihlal etmeyin


Bu sorunun neden herhangi bir olumlu oyu yok? onla ilgili yanlış bir şey mi var? slotsMakro olan ifadeyi yararlı buluyorum . Özel yuva işlevi işaretçilerini connecthileler olmadan bağlayamıyorum, değil mi?
Arch Linux Tux

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.