Qmetaobject feel with the class and so there is a spell, good learning

Source: Internet
Author: User

Provides a bunch of features that the original C + + does not have, such as reflection or something ... However, there may be more powerful classes that do not have Delphi, because classes can "create classes". Unfortunately I learned not fine, to "class and so on" did not fully learn. Leave a claw first, have time to learn two things well, then a comparison ...

-----------------------------------------------------------------------------------

In addition to the D pointer, another interesting part of QT is the q_object macro. The macro provides access to the meta-object, allowing more features such as qobject such as signals and slots to be used. Meta-objects provide information such as class names, properties, methods, and so on, also known as "reflection."


By using Qmetaobject, we are able to display some classes of information in the following code:

  1. Qobject obj;
  2. Const Qmetaobject *metaobj = Obj.metaobject ();
  3. Qdebug () << "class name:" << metaobj->classname ();
  4. Qdebug () << "Class info count:" << metaobj->classinfocount ();
  5. Qdebug () << "Methods:";
  6. Print from Qmetaobject::methodoffset () so that it does not display the method of the parent class
  7. for (int i = Metaobj->methodoffset (); I < Metaobj->methodcount (); ++i)
  8. Qdebug () << Metaobj->method (i). Methodtype () << "" << metaobj->method (i). Signature ();

Because C + + does not provide any support for this information, QT introduces the meta-object compiler (MOC) to do the work accordingly. The MOC reads each header file, and if it finds that the class it defines is inherited from Qobjectand defines the q_object macro, it creates a corresponding C + + source code file (moc_*.cpp) to do the work. Through the work of code generation, QT not only obtains the flexibility of languages such as Java, but also ensures the performance and extensibility of inheriting from C + +.

Let's say we have a simple class that looks like this:

    1. Class MyObject: Public qobject
    2. {
    3. Q_object
    4. Public
    5. explicit MyObject (Qobject *parent = 0);
    6. void MyFunc ();
    7. Public Slots:
    8. void Myslot (int myparam);
    9. Signals:
    10. void mysignal (int myparam);
    11. };

The MOC automatically creates the following information:

  1. Save in Qmetaobject::d. Data points to a space where the starting part is a qmetaobjectprivate struct
  2. Static const UINT Qt_meta_data_myobject[] = {
  3. 5, //version number, its internal structure has been changed in QT development
  4. 0, //class name, whose value is the offset of the string Qt_meta_stringdata_myobject
  5. //The following values are (quantity, index) pairs
  6. 0, 0, //class information
  7. 2, +//This defines two methods with a starting index of 14 (that is, the signal section)
  8. 0, 0, //Properties
  9. 0, 0, //enumeration
  10. 0, 0, //constructor
  11. 0, //Logo
  12. 1, //Signal Quantity
  13. //For signal, slots, and property, their signature and parameters are the offset of the string Qt_meta_stringdata_myobject
  14. //signals:signature, parameters, type, tag, flags
  15. 9, 9, 0x05,
  16. //slots:signature, parameters, type, tag, flags
  17. 9, 9, 0x0a,
  18. 0 //EOD
  19. };
  20. Save in Qmetaobject::d. StringData points to the space
  21. Static const Char qt_meta_stringdata_myobject[] = {
  22. "myobject/0/0myparam/0mysignal (int)/0"
  23. "Myslot (int)/0"
  24. };

The above information, and the related information of its base class, are stored in the corresponding meta-object of the class:

    1. Const Qmetaobject Myobject::staticmetaobject = {
    2. {&qobject::staticmetaobject, //The meta-object that points to its base class, saved in Qmetaobject::d. SuperData
    3. Qt_meta_stringdata_myobject, Qt_meta_data_myobject, 0}
    4. };

Thus, if we want to type-convert qobject objects , we do not need to use the expensive operator dynamic_cast, but we can use qobject_castdirectly. The template function takes advantage of the information of the meta-object system to avoid type conversions at run time:

    1. Template <class t> inline T qobject_cast (qobject *object)
    2. {
    3. #if!defined (Qt_no_qobject_check)
    4. reinterpret_cast (0)->qt_check_for_qobject_macro (*reinterpret_cast (object));
    5. #endif
    6. return static_cast (reinterpret_cast (0)->staticmetaobject.cast (object));
    7. }

Here, the meta-object of the target type simply checks to see if it inherits from itself:

  1. Const Qobject *qmetaobject::cast (const qobject *obj) const
  2. {
  3. if (obj) {
  4. const Qmetaobject *m = Obj->metaobject ();
  5. Do {
  6. if (m = = this )
  7. return obj;
  8. } while ((M = m->d.superdata));
  9. }
  10. return 0;
  11. }

In addition, the MOC creates a corresponding function for each signal . When the signal is emit, the function is automatically called:

    1. void myobject::mysignal (int _t1)
    2. {
    3. void *_a[] = {0, const_cast<void*> (reinterpret_cast<const void*> (&_T1))};
    4. //Check all slots linked to the signal and call according to the link type
    5. Qmetaobject::activate (This, &staticmetaobject, 0, _a);
    6. }

Finally, these signals are called through the qt_metacall function created by the MOC:

  1. int Myobject::qt_metacall (Qmetaobject::call _c, int _id, void **_a)
  2. {
  3. //If the function has been called by the base class, return directly
  4. _id = Qobject::qt_metacall (_c, _id, _a);
  5. if (_id < 0)
  6. return _id;
  7. //Call based on the ID of the function
  8. if (_c = = Qmetaobject::invokemetamethod) {
  9. switch (_id) {
  10. Case 0:mysignal ((*reinterpret_cast< Int (*) > (_a[1]));  Break ;
  11. Case 1:myslot ((*reinterpret_cast< Int (*) > (_a[1]));  Break ;
  12. default:;
  13. }
  14. //Delete the ID that is "consumed" by the class so that its subclass class will always start at 0 when the ID is processed, and a return value of 1 indicates that the function has been called
  15. _id-= 2;
  16. }
  17. return _id;
  18. }

Reference: http://blog.csdn.net/seanyxie/article/details/6120040

Qmetaobject feel with the class and so there is a spell, good learning

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.