Qt source code analysis: information hiding (2)

2010-06-04  来源:本站原创  分类:CPP  人气:295 

The following basis in the last one, we enter the Qt source code to see Qt4.x is how Private Classes for.

As we said earlier, perhaps you will see many similar Q_D or Q_Q kind of macro. So, let's try to look at code like this:

void MyClass::setFoo( int i )
{
        Q_D(MyClass);
        d->m_foo = i;
}

int MyClass::foo() const
{
        Q_D(const MyClass);
        return d->m_foo;
}

According to the traditional C + + class, if we are to achieve such a getter and setter, we should use a private variable _i, then operation of this variable. In accordance with the Private Class on an approach that, we will build a MyClassPrivateData this class, and then use that data for all operations were commissioned.

Look at a more Qt example:

class MyObject: public QObject
{
    Q_OBJECT

public:
    MyObject();
    virtual ~ MyObject();
    void setMemberX( int x );
    int memberX() const;
    void setMemberY( double y);
    double memberY() const;

signals:
    void priorityChanged( MyObject::Priority priority );

private:
    int        m_memberX;
    double m_memberY;

Qt implementation of the look:

class MyObjectPrivate;
class MyObject: public QObject
{
    Q_OBJECT

public:
    MyObject();
    virtual ~ MyObject();
    void setMemberX( int x );
    int memberX() const;
    void setMemberY( double y);
    double memberY() const;

signals:
    void priorityChanged( MyObject::Priority priority );

protected:
    MyObjectPrivate * const d_ptr;

private:
    Q_DECLARE_PRIVATE(MyObject);
};

This example is very simple, one using traditional methods to achieve the other methods used Qt4.x. Qt4.x method is called D-Pointer, because it uses a pointer called d, as written above, that d_ptr. Using traditional methods, we need to write in private which all the private variables, usually it makes the entire file becomes very long, more importantly, users do not need this information. The method of using the D-Pointer, we become very beautiful interface: no longer that long string of private variables. You no longer need to publish your private variable to go out with them on the inside of your d pointer. If you want to modify the data type information, you do not need to modify the header files, you can simply change the category of private data.

One thing to note is that with a simple C + + class is different from the private class if you need to define signals and slots, this definition should be placed on the header file, rather than the one mentioned on the cpp file. This is because the qmake will detect. H file in the Q_OBJECT macro (which you must pay attention). Of course, you should not put such a private class on your head and file the same class, because doing so does not make sense. Common practice is to define a private header file, such as the use myclass_p.h naming (this is also the naming Qt). And remember, do not put private header files include the following you posted! Because this is not a part of your release, they are private. Then, in your myclass header files, use the

class MyClassPrivate;

This statement is not forward directly

#include "myclass_p.h"

In this way. This is to avoid the private header file, publish and declare before the compile time can be shortened.

In this class, private parts, we use a MyClassPrivate the const pointer d_ptr. If you need to subclass this class can use this guide should be on the protected part of this d_ptr, as the above code as. And, we also added the const keyword to ensure that it can only be initialized once.

Next, we met a wonderful macro: Q_DECLARE_PRIVATE. This is for? So, let's look at the start of this macro:

#define Q_DECLARE_PRIVATE(Class) \
    inline Class##Private* d_func() { return reinterpret_cast(qGetPtrHelper(d_ptr)); } \
    inline const Class##Private* d_func() const { return reinterpret_cast(qGetPtrHelper(d_ptr)); } \
    friend class Class##Private;

If you look not know, then use our Q_DECLARE_PRIVATE (MyClass) start to see what followed it:

inline MyClassPrivate* d_func() { return reinterpret_cast(qGetPtrHelper(d_ptr)); }
    inline const MyClassPrivate* d_func() const { return reinterpret_cast(qGetPtrHelper(d_ptr)); }
    friend class MyClassPrivate;

It actually creates two inline of d_func () function, the return value are our d_ptr pointer and const pointer. In addition, it declared the MyClassPrivate class MyClass's friend. In this case, we can use in which the class MyClass Q_D (MyClass) and Q_D (const MyClass). Remember when we first saw that part of code? Now we take a look at this Q_D Dao Shi is and source!

// A template function for getting the instance to your private class instance.
template  static inline T *qGetPtrHelper(T *ptr) { return ptr; }

// A macro for getting the d-pointer
#define Q_D(Class) Class##Private * const d = d_func()

Or start following his look at the macro, it becomes

MyClassPrivate * const d = d_func()

In short, Qt for us to from d_func () to obtain MyClassPrivate pointer to package up the code, so that we can compare the use of object-oriented getter function to get the pointer.

Now that we have a rather clear that Qt is how to use D-Pointer to achieve what we have in front of the hidden information. However, there is a problem: If we concentrate MyClassPrivate most of the code inside, it may need to make implementation of the access to MyClass MyClassPrivate something. Now we get the main class through the D-Pointer access MyClassPrivate the data, but how in turn the main class to MyClassPrivate access data? Qt also provides the appropriate solution, that is Q_Q macro, for example:

class MyObjectPrivate
{
public:
    MyObjectPrivate(MyObject * parent):
            q_ptr( parent ),
            m_priority(MyObject::Low)
    {}
    void foo()
    {
        // Demonstrate how to make MyObject to emit a signal
        Q_Q(MyObject);
        emit q->priorityChanged( m_priority );
    }

    //  Members
    MyObject * const q_ptr;
    Q_DECLARE_PUBLIC(MyObject);
    MyObject::Priority m_priority;
};

In the private class MyObjectPrivate in the main class through the constructor MyObject the pointer to q_ptr. Then we use a similar use of Q_DECLARE_PRIVATE main class as the other macro macro Q_DECLARE_PUBLIC. This macro does is make you able to Q_Q (Class) macro to use the main class pointer. And D-Pointer different, this time you need to use the Q_Pointer. The two are entirely relative, also will not repeat them here.

Now we have been able to use more ways to use Qt Private Classes realize information hidden. This is not just the realization of Qt, of course, you can not Q_D and Q_Q, but the use of their own way, these are irrelevant. Most importantly, we know a C + + class design ideas, this is the source code of Qt taught us.

相关文章
  • Qt source code analysis: information hiding (2) 2010-06-04

    The following basis in the last one, we enter the Qt source code to see Qt4.x is how Private Classes for. As we said earlier, perhaps you will see many similar Q_D or Q_Q kind of macro. So, let's try to look at code like this: void MyClass::setFoo( i

  • Qt source code analysis: information hiding (1) 2010-06-02

    If you read Qt's source code, you'll see a bunch of weird macro, for example Q_D, Q_Q. Qt source of our journey to understand the macro from the start with. The following look at a C + + example. class Person { public: Person(){} ~Person(){} string n

  • Qt source code analysis: information hiding (3) 2010-06-19

    We have seen above how to use the standard C + + code and the Qt API provided to achieve the goal of information hiding. Here is how we look at the Qt implementation. Or in QObject source code as an example. First open qobject.h, find QObjectData thi

  • Qt source code analysis: starting from QObject 2010-06-02

    Originally intended to "Qt way of learning" as something of a similar tutorial, so do not intend to put some content related to the source code on that line among friends. So today the first look at a new start! Progress in this series are not e

  • Android IPC communication mechanism for source code analysis 2010-06-10

    Android IPC communication mechanism for source code analysis Binder Communications Description: Linux system, inter-process communication methods are: socket, named pipe, message queque, signal, share memory. Java System inter-process communication w

  • Spring source code analysis (4): Spring MVC 2009-10-24

    The following Spring MVC framework of the code we analyzed, for webApplicationContext correlation analysis can be found in the previous document, we are here to focus on analysis of Spring Web MVC framework for implementation. DispatcherServlet we st

  • Spring source code analysis (6): Spring declarative transaction processing 2009-11-30

    We take a look at Spring's transaction code, the use of Spring Management Services are two kinds of declarative and programmatic way through the AOP declarative transaction management code to achieve the things as a package to horizontal aspects of t

  • Spring source code analysis (8): Spring-driven implementation of Hibernate 2009-03-26

    O / R tool came to simplify the complex information of many persistent development. Spring application developers through the Spring provides O / R program is more convenient to use a variety of persistence tools, such as Hibernate; Here we have Spri

  • Tomcat 5.5.26 source code analysis - start the process (2) 2010-03-25

    init method Catalina_Home and Catalina_Base Initialize the system class loader Tomcat's class loader system initClassLoaders code Two questions Catalina Object load method Catalina class command-line arguments Loading process start Method await state

  • Mysql source code analysis series 2010-03-30

    Mysql source code analysis series (2): the source code structure Mysql source code include the client code, server-side code, testing tools and some database structure, the following directories we do introduce the more important. BUILD This director

  • iBATIS source code analysis framework 2010-07-06

    iBATIS source code analysis framework Basic Information Of: any steel Publisher: Electronic Industry Press ISBN: 9787121108723 Added time :2010-7-2 Publication Date: June 2010 format: 16 Open Page: 510 For more details, please see: http://www.china-p

  • SQLite source code analysis (6) 2010-07-29

    / * ** Add the ability to override 'extern' * / / / Extern macro definitions can be used to complete the extern function SQLITE_EXTERN # Ifndef SQLITE_EXTERN # Define SQLITE_EXTERN extern # Endif / / Define macro SQLITE_API # Ifndef SQLITE_API # Defi

  • junit part of the source code analysis 2010-10-02

    junit part of the source code analysis By a rough understanding of Junit, roughly the know and there's several modes: junit source associated spring, hibnate source than the relatively simple, but the small but perfectly formed, and there used severa

  • One of the server source code analysis Tracker: Overview 2010-10-13

    One of the server source code analysis Tracker: Overview Of: Ma Ying-jeou Date :2004-5-29 BT download tracker server is necessary role. Start a BT client and a download in the download process, to keep the server to communicate with the tracker to re

  • (R) linux source code analysis and comparative reading tools 2010-11-01

    Reprinted from: http://hi.baidu.com/likeadream/blog/item/7664bb349daf0049241f144c.html Windows source code under the reading tool Souce Insight by virtue of its ease of use and variety of programming languages, this area is undoubtedly the "take the

  • Struts2.2.1 a core source code analysis 2010-11-30

    I. Overview Struts2 is the core of a Filter, Action from the web container can be, then what makes http request and the action associated with, the following source code to our in-depth analysis of how the work under the Struts2. FilterDispatcher API

  • (Transfer) MapReduce source code analysis summary 2011-05-03

    Original Address: http://www.cnblogs.com/end/archive/2011/04/26/2029499.html Transferred by Note: The summary originally wanted to study in the series of detailed analysis Hadoop HDFS and Map-Reduce, however, when searching for information and found

  • Glibc memory management - ptmalloc2 source code analysis (l) 2011-05-30

    5. Source Code Analysis Are two main techniques for the details of the source code for analysis, hoping to further understand ptmalloc implementation, to achieve the ultimate free from doubts. The documents include the main analysis arena.c and mallo

  • (R) linux source code analysis tools, and read more 2010-11-01

    Reprinted from: http://hi.baidu.com/likeadream/blog/item/7664bb349daf0049241f144c.html Reading tool for Windows source code Souce Insight With its ease of use and a variety of programming languages, no doubt in this area, "lead Big Brother." Lin

  • Glibc memory management - ptmalloc2 source code analysis (XII) 2011-05-30

    5 source code analysis The main points of the source code to analyze the details of technique, hoping to achieve a better understanding of ptmalloc, so that the ultimate no confusion. Including the analysis of the main arena.c and malloc.c, these two