ChatGPT解决这个技术问题 Extra ChatGPT

Qt "private slots:" what is this?

I understand how to use it, but the syntax of it bothers me. What is "private slots:" doing?

I have never seen something between the private keyword and the : in a class definition before. Is there some fancy C++ magic going on here?

And example here:

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

 ...
This is not Standard C++, This is QT framework construct. Lookup QT signals and slots.
When compiling as C++ slots is defined as #define slots. When compiling using Qt MOC it generates code for the C++ compiler.
lol this was even harder for me to understand because i havent used C++ in so long, i thought they added something new

C
Christophe Weis

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.
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.
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.
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.
A
Andrew

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


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 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.
@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.
E
Euri Pinhollow

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?
I think "Consequently you won't be able to pass private slots address to connect." contradicts @Andrew answer (which I think is the clearest), isn't?
@KcFnMi you can connect any signals and slots you want regardless of their relationship between each other - if you have their pointers. That does not change the fact that you cannot reference private slots and signals by their identifier when they are not visible. I do not remember exactly but even using text strings as identifiers probably does not work either.
Because it expands into the reference to the actual signal or slot requested.