QT 元编译器

Why Does Qt Use Moc for Signals and Slots?
Templates are a builtin mechanism in C++ that allows the compiler to generate code on the fly, depending on the type of the arguments passed. As such, templates are highly interesting to framework creators, and we do use advanced templates in many places in Qt. However, there are limitations: There are things that you can easily express with templates, and there are things that are impossible to express with templates. A generic vector container class is easily expressible, even with partial specialisation for pointer types, while a function that sets up a graphical user interface based on an XML description given as a string is not expressible as a template. And then there is a gray area in between. Things that you can hack with templates at the cost of code size, readability, portability, usability, extensability, robustness and ultimately design beauty. Both templates and the C preprocessor can be stretched to do incredibility smart and mind boggling things. But just because those things can be done, it does not necessarily mean doing them is the right design choice. Code, unfortunately, is not meant to be published in books, but compiled with real-world compilers on real-world operating systems.
Here are some reasons why Qt uses the moc:

Syntax Matters
Syntax isn’t just sugar: the syntax we use to express our algorithms can significantly affect the readability and maintainability of our code. The syntax used for Qt’s signals and slots has proved very successful in practice. The syntax is intuitive, simple to use and easy to read. People learning Qt find the syntax helps them understand and utilize the signals and slots concept – despite its highly abstract and generic nature. This helps programmers get their design right from the very beginning, without even having to think about design patterns.

Code Generators are Good
Qt’s moc (Meta Object Compiler) provides a clean way to go beyond the compiled language’s facilities. It does so by generating additional C++ code which can be compiled by any standard C++ compiler. The moc reads C++ source files. If it finds one or more class declarations that contain the Q_OBJECT macro, it produces another C++ source file which contains the meta object code for those classes. The C++ source file generated by the moc must be compiled and linked with the implementation of the class (or it can be #included into the class’s source file). Typically moc is not called manually, but automatically by the build system, so it requires no additional effort by the programmer.
The moc is not the only code generator Qt is using. Another prominent example is the uic (User Interface Compiler). It takes a user interface description in XML and creates C++ code that sets up the form. Outside Qt, code generators are common as well. Take for example rpc and idl, that enable programs or objects to communicate over process or machine boundaries. Or the vast variety of scanner and parser generators, with lex and yacc being the most well-known ones. They take a grammar specification as input and generate code that implements a state machine. The alternatives to code generators are hacked compilers, proprietary languages or graphical programming tools with one-way dialogs or wizards that generate obscure code during design time rather than compile time. Rather than locking our customers into a proprietary C++ compiler or into a particular Integrated Development Environment, we enable them to use whatever tools they prefer. Instead of forcing programmers to add generated code into source repositories, we encourage them to add our tools to their build system: cleaner, safer and more in the spirit of UNIX.

GUIs are Dynamic
C++ is a standarized, powerful and elaborate general-purpose language. It’s the only language that is exploited on such a wide range of software projects, spanning every kind of application from entire operating systems, database servers and high end graphics applications to common desktop applications. One of the keys to C++'s success is its scalable language design that focuses on maximum performance and minimal memory consumption whilst still maintaining ANSI C compatibility.
For all these advantages, there are some downsides. For C++, the static object model is a clear disadvantage over the dynamic messaging approach of Objective C when it comes to component-based graphical user interface programming. What’s good for a high end database server or an operating system isn’t necessarily the right design choice for a GUI frontend. With moc, we have turned this disadvantage into an advantage, and added the flexibility required to meet the challenge of safe and efficient graphical user interface programming.
Our approach goes far beyond anything you can do with templates. For example, we can have object properties. And we can have overloaded signals and slots, which feels natural when programming in a language where overloads are a key concept. Our signals add zero bytes to the size of a class instance, which means we can add new signals without breaking binary compatibility.
Another benefit is that we can explore an object’s signals and slots at runtime. We can establish connections using type-safe call-by-name, without having to know the exact types of the objects we are connecting. This is impossible with a template based solution. This kind of runtime introspection opens up new possibilities, for example GUIs that are generated and connected from Qt Designer’s XML UI files.

No Limits
Because we had the moc for signals and slots, we could add other useful things to it that could not be done with templates. Among these are scoped translations via a generated tr() function, and an advanced property system with introspection and extended runtime type information. The property system alone is a great advantage: a powerful and generic user interface design tool like Qt Designer would be a lot harder to write - if not impossible - without a powerful and introspective property system. But it does not end here. We also provide a dynamic qobject_cast() mechanism that does not rely on the system’s RTTI and thus does not share its limitations. We use it to safely query interfaces from dynamically loaded components. Another application domain are dynamic meta objects. We can e.g. take ActiveX components and at runtime create a meta object around it. Or we can export Qt components as ActiveX components by exporting its meta object. You cannot do either of these things with templates.
C++ with the moc essentially gives us the flexibility of Objective-C or of a Java Runtime Environment, while maintaining C++'s unique performance and scalability advantages. It is what makes Qt the flexible and comfortable tool we have today.

Qt支持三种类型的信号-槽连接:
1,直接连接,当signal发射时,slot立即调用。此slot在发射signal的那个线程中被执行(不一定是接收对象生存的那个线程)
2,队列连接,当控制权回到对象属于的那个线程的事件循环时,slot被调用。此slot在接收对象生存的那个线程中被执行
3,自动连接(缺省),假如信号发射与接收者在同一个线程中,其行为如直接连接,否则,其行为如队列连接。
连接类型可能通过以向connect()传递参数来指定。注意的是,当发送者与接收者生存在不同的线程中,而事件循环正运行于接收者的线程中,使用直接连接是不安全的。同样的道理,调用生存在不同的线程中的对象的函数也是不是安全的。QObject::connect()本身是线程安全的。

QT 待完善

你可能感兴趣的:(QT,C++)