Qt “vùng riêng tư:” đây là gì?


82

Tôi hiểu cách sử dụng nó, nhưng cú pháp của nó làm tôi khó chịu. "Vùng riêng tư:" đang làm gì?

Tôi chưa bao giờ thấy điều gì đó giữa từ khóa private và: trong định nghĩa lớp trước đây. Có một số phép thuật C ++ ưa thích đang diễn ra ở đây không?

Và ví dụ ở đây:

 #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
This is not Standard C++, This is QT framework construct. Lookup QT signals and slots.
Alok Save

1
When compiling as C++ slots is defined as #define slots. When compiling using Qt MOC it generates code for the C++ compiler.
dalle

2
lol this was even harder for me to understand because i havent used C++ in so long, i thought they added something new
dtc

Câu trả lời:


56

Slots are a Qt-specific extension of C++. It only compiles after sending the code through Qt's preprocessor, the Meta-Object Compiler (moc). See http://doc.qt.io/qt-5/moc.html for documentation.

Edit: As Frank points out, moc is only required for linking. The extra keywords are #defined away with the standard preprocessor.


Thanks, Qt's preprocessor is what I was missing in my mental model of what was going on.
Justin

16
Not correct, the code compiles all the time as "signals" and "slots" are empty defines so the compiler never sees them. These macros are hints for moc, which generates additional code. The original .h and .cpp files are not altered and compile just fine without moc. What would fail is linking, as the moc-generated definitions (signal definitions, metaobject, etc.) are otherwise missing.
Frank Osterfeld

1
Is the slots keyword necessary? I've tried compiling/linking a few tiny Qt programs that call slots without the slots keyword and they have built just fine. My experiments show that: signals: is definitely necessary, slots might be unnecessary, and emit seems to be unnecessary as I've read elsewhere.
It's Your App LLC

1
slots is not necessary in Qt5. Qt updated the connect() syntax to allow for connecting a signal to an arbitrary function, including lambdas. Because of this, slots is not necessary. However, the slots keyword still affects the way that an object's QMetaObject is built. moc (aka, the "meta-object compiler") won't recognize a method as a slot unless it is within the slots: section of a class definition. So, although the connection will still work, the method will not show up in introspection tools.
Chris

19

The keywords such as public, private are ignored for Qt slots. All slots are actually public and can be connected


30
When the method is called via signal/slot mechanism, the access specifiers are ignored. But slots are also "normal" methods. When you call them using the traditional way, the access specifiers are considered.
borges

4
@borges and any future readers. In Qt5 the connect() method can use function pointers (which has advantages). If you connect with function pointers then the access specifiers are enforced in the signals/slots mechanism.
Tod

3
@borges I believe this is incorrect, or at least the explanation was unclear. The access specifiers do not restrict your ability to connect signals to slots; that is, a private slot can be connected to any signal. The access specifier does, however, protect the member function from its class (in the typical way) while it's being invoked. So, the access specifiers aren't "ignored" when called via the signal/slot mechanism: they have no bearing on connecting slots to signals, but they do protect the function from this in the way we are familiar with.
It's Your App LLC

4

Declaring slots as private means that you won't be able to reference them from context in which they are private, like any other method. Consequently you won't be able to pass private slots address to connect.

If you declare signal as private you are saying that only this class can manage it but function member pointers do not have access restrictions:

class A{
    private:
    void e(){

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

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

Other than that, what other answers mention is valid too:
- you still can connect private signals and slots from outside with tricks
- signals and slots are empty macros and do not break language standard


Why does this question not have any upvotes? Is there something wrong with it? I find the statement, that slots is a macro helpful. I cannot connect private slot-function-pointers to connect without tricks, can I?
Arch Linux Tux

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.