source: trunk/doc/src/frameworks-technologies/templates.qdoc@ 568

Last change on this file since 568 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

  • Property svn:eol-style set to native
File size: 12.8 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the documentation of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42/*!
43 \page templates.html
44 \title Why Doesn't Qt Use Templates for Signals and Slots?
45 \brief The reasoning behind Qt's implementation of signals and slots.
46
47 Templates are a builtin mechanism in C++ that allows the compiler to
48 generate code on the fly, depending on the type of the arguments
49 passed. As such, templates are highly interesting to framework
50 creators, and we do use advanced templates in many places
51 in Qt. However, there are limitations: There are things that you can
52 easily express with templates, and there are things that are
53 impossible to express with templates. A generic vector container class
54 is easily expressible, even with partial specialisation for pointer
55 types, while a function that sets up a graphical user interface based
56 on a XML description given as a string is not expressible as
57 template. And then there is gray area in between. Things that you can
58 hack with templates at the cost of code size, readability,
59 portability, usability, extensability, robustness and ultimately
60 design beauty. Both templates and the C preprocessor can be stretched
61 to do incredibility smart and mind boggling things. But just because
62 those things can be done, does not necessarily mean doing them is the
63 right design choice.
64
65 There is an important practical challenge we have to mention: due to
66 the inadequacies of various compilers it is still not possible to
67 fully exploit the template mechanism in cross-platform
68 applications. Code unfortunately is not meant to be published in
69 books, but compiled with real-world compilers on real-world operating
70 system. Even today, many widely used C++ compilers have problems with
71 advanced templates. For example, you cannot safely rely on partial
72 template specialisation, which is essential for some non-trivial
73 problem domains. Some compilers also have limitations with regards to
74 template member functions, which make it hard to combine generic
75 programming with object orientated programming. However, we do not
76 perceive these problems as a serious limitation in our work. Even if
77 all our users had access to a fully standards compliant modern C++
78 compiler with excellent template support, we would not abandon the
79 string-based approach used by our meta object compiler for a template
80 based signals and slots system. Here are five reasons why:
81
82 \section1 Syntax matters
83
84 Syntax isn't just sugar: the syntax we use to express our algorithms can
85 significantly affect the readability and maintainability of our code.
86 The syntax used for Qt's signals and slots has proved very successful in
87 practice. The syntax is intuitive, simple to use and easy to read.
88 People learning Qt find the syntax helps them understand and utilize the
89 signals and slots concept -- despite its highly abstract and generic
90 nature. Furthermore, declaring signals in class definitions ensures that
91 the signals are protected in the sense of protected C++ member
92 functions. This helps programmers get their design right from the very
93 beginning, without even having to think about design patterns.
94
95 \section1 Code Generators are Good
96
97 Qt's \c{moc} (Meta Object Compiler) provides a clean way to go
98 beyond the compiled language's facilities. It does so by generating
99 additional C++ code which can be compiled by any standard C++ compiler.
100 The \c{moc} reads C++ source files. If it finds one or more class
101 declarations that contain the Q_OBJECT macro, it produces another C++
102 source file which contains the meta object code for those classes. The
103 C++ source file generated by the \c{moc} must be compiled and
104 linked with the implementation of the class (or it can be
105 \c{#included} into the class's source file). Typically \c{moc}
106 is not called manually, but automatically by the build system, so it
107 requires no additional effort by the programmer.
108
109 The \c{moc} is not the only code generator Qt is using. Another
110 prominent example is the \c{uic} (User Interface Compiler). It
111 takes a user interface description in XML and creates C++ code that
112 sets up the form. Outside Qt, code generators are common as well. Take
113 for example \c{rpc} and \c{idl}, that enable programs or
114 objects to communicate over process or machine boundaries. Or the vast
115 variety of scanner and parser generators, with \c{lex} and
116 \c{yacc} being the most well-known ones. They take a grammar
117 specification as input and generate code that implements a state
118 machine. The alternatives to code generators are hacked compilers,
119 proprietary languages or graphical programming tools with one-way
120 dialogs or wizards that generate obscure code during design time
121 rather than compile time. Rather than locking our customers into a
122 proprietary C++ compiler or into a particular Integrated Development
123 Environment, we enable them to use whatever tools they prefer. Instead
124 of forcing programmers to add generated code into source repositories,
125 we encourage them to add our tools to their build system: cleaner,
126 safer and more in the spirit of UNIX.
127
128
129 \section1 GUIs are Dynamic
130
131 C++ is a standarized, powerful and elaborate general-purpose language.
132 It's the only language that is exploited on such a wide range of
133 software projects, spanning every kind of application from entire
134 operating systems, database servers and high end graphics
135 applications to common desktop applications. One of the keys to C++'s
136 success is its scalable language design that focuses on maximum
137 performance and minimal memory consumption whilst still maintaining
138 ANSI C compatibility.
139
140 For all these advantages, there are some downsides. For C++, the static
141 object model is a clear disadvantage over the dynamic messaging approach
142 of Objective C when it comes to component-based graphical user interface
143 programming. What's good for a high end database server or an operating
144 system isn't necessarily the right design choice for a GUI frontend.
145 With \c{moc}, we have turned this disadvantage into an advantage,
146 and added the flexibility required to meet the challenge of safe and
147 efficient graphical user interface programming.
148
149 Our approach goes far beyond anything you can do with templates. For
150 example, we can have object properties. And we can have overloaded
151 signals and slots, which feels natural when programming in a language
152 where overloads are a key concept. Our signals add zero bytes to the
153 size of a class instance, which means we can add new signals without
154 breaking binary compatibility. Because we do not rely on excessive
155 inlining as done with templates, we can keep the code size smaller.
156 Adding new connections just expands to a simple function call rather
157 than a complex template function.
158
159 Another benefit is that we can explore an object's signals and slots at
160 runtime. We can establish connections using type-safe call-by-name,
161 without having to know the exact types of the objects we are connecting.
162 This is impossible with a template based solution. This kind of runtime
163 introspection opens up new possibilities, for example GUIs that are
164 generated and connected from Qt Designer's XML UI files.
165
166 \section1 Calling Performance is Not Everything
167
168 Qt's signals and slots implementation is not as fast as a
169 template-based solution. While emitting a signal is approximately the
170 cost of four ordinary function calls with common template
171 implementations, Qt requires effort comparable to about ten function
172 calls. This is not surprising since the Qt mechanism includes a
173 generic marshaller, introspection, queued calls between different
174 threads, and ultimately scriptability. It does not rely on excessive
175 inlining and code expansion and it provides unmatched runtime
176 safety. Qt's iterators are safe while those of faster template-based
177 systems are not. Even during the process of emitting a signal to
178 several receivers, those receivers can be deleted safely without your
179 program crashing. Without this safety, your application would
180 eventually crash with a difficult to debug free'd memory read or write
181 error.
182
183 Nonetheless, couldn't a template-based solution improve the performance
184 of an application using signals and slots? While it is true that Qt adds
185 a small overhead to the cost of calling a slot through a signal, the
186 cost of the call is only a small proportion of the entire cost of a
187 slot. Benchmarking against Qt's signals and slots system is typically
188 done with empty slots. As soon as you do anything useful in your slots,
189 for example a few simple string operations, the calling overhead becomes
190 negligible. Qt's system is so optimized that anything that requires
191 operator new or delete (for example, string operations or
192 inserting/removing something from a template container) is significantly
193 more expensive than emitting a signal.
194
195 Aside: If you have a signals and slots connection in a tight inner loop
196 of a performance critical task and you identify this connection as the
197 bottleneck, think about using the standard listener-interface pattern
198 rather than signals and slots. In cases where this occurs, you probably
199 only require a 1:1 connection anyway. For example, if you have an object
200 that downloads data from the network, it's a perfectly sensible design
201 to use a signal to indicate that the requested data arrived. But if you
202 need to send out every single byte one by one to a consumer, use a
203 listener interface rather than signals and slots.
204
205 \section1 No Limits
206
207 Because we had the \c{moc} for signals and slots, we could add
208 other useful things to it that could not be done with templates.
209 Among these are scoped translations via a generated \c{tr()}
210 function, and an advanced property system with introspection and
211 extended runtime type information. The property system alone is a
212 great advantage: a powerful and generic user interface design tool
213 like Qt Designer would be a lot harder to write - if not impossible -
214 without a powerful and introspective property system. But it does not
215 end here. We also provide a dynamic qobject_cast<T>() mechanism
216 that does not rely on the system's RTTI and thus does not share its
217 limitations. We use it to safely query interfaces from dynamically
218 loaded components. Another application domain are dynamic meta
219 objects. We can e.g. take ActiveX components and at runtime create a
220 meta object around it. Or we can export Qt components as ActiveX
221 components by exporting its meta object. You cannot do either of these
222 things with templates.
223
224 C++ with the \c{moc} essentially gives us the flexibility of
225 Objective-C or of a Java Runtime Environment, while maintaining C++'s
226 unique performance and scalability advantages. It is what makes Qt the
227 flexible and comfortable tool we have today.
228
229*/
Note: See TracBrowser for help on using the repository browser.