doc/src/frameworks-technologies/templates.qdoc
branchRCL_3
changeset 8 3f74d0d4af4c
equal deleted inserted replaced
6:dee5afe5301f 8:3f74d0d4af4c
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the documentation of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    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 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    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 */