Qt代码是如何转为C++代码的?

发布于 2020-02-21  381 次阅读


前言

关于想写这篇博客也是我跟知乎上的某个大佬撕逼来引出来的问题。

因为我发现某大佬把编译期跟运行期搞混了。

还跟我大谈特谈什么Template之类的,还引出了Qt官方的博客,截取了一部分出来,恰好!!恰好我仔细读过Qt的这篇官方文档,发现他给的论据一点用都没有,而且也没说到点上,还是我来简单进行科普下。

先抛出问题以及思考

Qt5的新语法与Qt4的语法运行效率有差别么?


connect(sender, SIGNAL(valueChanged(QString, QString)), receiver, SLOT(updateValue(QString))); //Qt4 connect(sender, &Sender::valueChanged, receiver, &Receiver::updateValue); //Qt5

接下来该谈C++基础了

一个在刚学C++的学生应该就清楚,一个完整的C++代码到可执行程序的过程

  • 预编译 编译 汇编 链接

Qt是如何做的?

那么Qt是如何把非标准的C++代码,转化成可执行程序呢?我们举个例子

在Linux下比如我们新建了一个工程

有这么几个文件


main.cpp mainwindow.cpp mainwindow.h mainwindow.ui untitled6.pro

然后执行qmake untitled6.pro

会生成一个Makefile文件

简单贴上一部分Makefile的代码


//。。。 compiler_moc_header_clean: -$(DEL_FILE) moc_mainwindow.cpp moc_mainwindow.cpp: ../untitled6/mainwindow.h /media/zhangpf/workspace1/Qt4.8.7/build_debug/bin/moc $(DEFINES) $(INCPATH) ../untitled6/mainwindow.h -o moc_mainwindow.cpp //。。。

仔细看这部分代码

然后直接make

发现生成了这么几个文件


main.o mainwindow.o moc_mainwindow.cpp moc_mainwindow.o ui_mainwindow.h untitled6

跟标准C++的编译过程对比的话,多出来这么几个文件


moc_mainwindow.cpp moc_mainwindow.o ui_mainwindow.h

观察下编译过程

// 这个太长,我提取下关键信息

/usr/lib/x86_64-linux-gnu/qt5/bin/uic ../mainwindow.ui -o ui_mainwindow.h
g++ -c -m64 -pipe -O2 -std=gnu++0x -Wall -W -D_REENTRANT -fPIC -DQT_DEPRECATED_WARNINGS -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I../../untitled6 -I. -isystem /usr/include/x86_64-linux-gnu/qt5 -isystem /usr/include/x86_64-linux-gnu/qt5/QtWidgets -isystem /usr/include/x86_64-linux-gnu/qt5/QtGui -isystem /usr/include/x86_64-linux-gnu/qt5/QtCore -I. -I. -I/usr/lib/x86_64-linux-gnu/qt5/mkspecs/linux-g++-64 -o main.o ../main.cpp
g++ -c -m64 -pipe -O2 -std=gnu++0x -Wall -W -D_REENTRANT -fPIC -DQT_DEPRECATED_WARNINGS -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I../../untitled6 -I. -isystem /usr/include/x86_64-linux-gnu/qt5 -isystem /usr/include/x86_64-linux-gnu/qt5/QtWidgets -isystem /usr/include/x86_64-linux-gnu/qt5/QtGui -isystem /usr/include/x86_64-linux-gnu/qt5/QtCore -I. -I. -I/usr/lib/x86_64-linux-gnu/qt5/mkspecs/linux-g++-64 -o mainwindow.o ../mainwindow.cpp
/usr/lib/x86_64-linux-gnu/qt5/bin/moc -DQT_DEPRECATED_WARNINGS -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I/usr/lib/x86_64-linux-gnu/qt5/mkspecs/linux-g++-64 -I/home/zhangpf/QtProject/untitled6 -I/usr/include/x86_64-linux-gnu/qt5 -I/usr/include/x86_64-linux-gnu/qt5/QtWidgets -I/usr/include/x86_64-linux-gnu/qt5/QtGui -I/usr/include/x86_64-linux-gnu/qt5/QtCore -I. -I/usr/include/c++/5 -I/usr/include/x86_64-linux-gnu/c++/5 -I/usr/include/c++/5/backward -I/usr/lib/gcc/x86_64-linux-gnu/5/include -I/usr/local/include -I/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed -I/usr/include/x86_64-linux-gnu -I/usr/include ../mainwindow.h -o moc_mainwindow.cpp
g++ -c -m64 -pipe -O2 -std=gnu++0x -Wall -W -D_REENTRANT -fPIC -DQT_DEPRECATED_WARNINGS -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I../../untitled6 -I. -isystem /usr/include/x86_64-linux-gnu/qt5 -isystem /usr/include/x86_64-linux-gnu/qt5/QtWidgets -isystem /usr/include/x86_64-linux-gnu/qt5/QtGui -isystem /usr/include/x86_64-linux-gnu/qt5/QtCore -I. -I. -I/usr/lib/x86_64-linux-gnu/qt5/mkspecs/linux-g++-64 -o moc_mainwindow.o moc_mainwindow.cpp
g++ -m64 -Wl,-O1 -o untitled6 main.o mainwindow.o moc_mainwindow.o -L/usr/X11R6/lib64 -lQt5Widgets -lQt5Gui -lQt5Core -lGL -lpthread

精简版

/usr/lib/x86_64-linux-gnu/qt5/bin/uic ../mainwindow.ui -o ui_mainwindow.h
/usr/lib/x86_64-linux-gnu/qt5/bin/moc xxxxxx  ../mainwindow.h -o moc_mainwindow.cpp

关键信息

qt的uic可执行程序把ui文件转成了文件 ui_mainwindow.h
qt的moc可执行程序把Qt的非标准c++语法转成了标准c++语法,并生成 moc_mainwindow.cpp

ui_mainwindow.h, moc_mainwindow.cpp 这俩文件中代码的语法都是标准C++代码

也就是不管Qt的新的语法变形成什么鬼样子,最后都会转成标准C++语法,来继续 预编译 编译 汇编 链接 这个过程。

Qt代码编译的过程也就多了一步
把Qt的代码转化成标准C++的代码。

都转化成了标准C++语法了,效率还有差别么?
如果有人会疑问,如果两个语法最后moc生成的C++代码不一样,导致运行效率不一样怎么办?

换位思考下。假如你是Qt的开发负责人,你会干这样(不是人)的事儿么?

当然我这次并不讨论Qt5支持的新的lambda表达式。如果有兴趣可以自己看下moc生成的文件。
如果有兴趣看Qt5新加的Lambda表达式与原来SIGNAL,SLOT的差异,下次再写

结论

Qt4跟Qt5的同样功能的connect的不同写法,对于运行效率肯定是一样的。

所以基础是多么的重要!逃)

欢迎关注我的小程序,小程序内容与网站自动保持同步

欢迎关注我的微信公众号,本网站所有的文章以及更新以后都会手动同步到微信公众号上。


公交车司机终于在众人的指责中将座位让给了老太太