由《一道QT小题》想到的~
时间:2010-11-12 来源:landuochong
偶然的一个机会,读到了CSDN推荐的一篇blog:《一道Qt小题考考你》。原题引用如下:
请问下面的Qt代码有什么问题?
#include <QtGui/QApplication>
#include <QtGui/QLabel>
#include <QtGui/QWidget>
int main(int argc, char* argv[])
{
QApplication hwApp(argc, argv);
QLabel hwLabel("http://www.cuteqt.com/blog");
QWidget window;
hwLabel.setParent(&window);
window.show();
return hwApp.exec();
}
我读懂了这段小代码,也看出了问题的所在,虽然我从来没有使用过QT。这说明QT的类库设计得很不错,起码简单易懂。
如原文所述,上述代码的问题在于window对象和hwLabel对象的析构顺序反了,解决的方法也很简单,将windows对象和hwLabel对象的声明语句调换顺序即可。
一点思考
当然,现在我专门写一篇blog,不是要赞一下QT,也不是要再次强调一下C++程序都会面临的对象析构的顺序问题。
很明显,QT对于界面的抽象和当下许多流行的做法一样,即将程序窗口及窗口控件抽象成一棵对象树。从最终界面呈现的角度讲,上述代码逻辑中的hwLabel总是需要依赖一个window才有存在的意义,于是setParent或者类似的接口总是必须存在的。
一方面,这里必定会存在两个有父子关系的对象;另一方面,对象的析构顺序也存在约束。而我的问题是,有没有一种编程方法能够做到当这两个对象声明顺序相反的时候,编译器就会报错?或者,有没有一种编程风格压根就不care对象声明的顺序呢?
对于我自己抛出来的上述两问,我当然是作过一点思考,也做过一点尝试的。一种解决方法是,将setParent的功能提前到hwLabel的构造函数;极端一点,只允许使用引用!另一种解决方法是向DotNet等框架学习,提倡一种全部使用动态对象的风格。
一点结论
当然,真正实践的时候,总是会有一些理论所预期不到的问题。上述的解决方法遇到实际的场景也必定是各有利弊。
无论是对于开发人员来讲,还是对于应用本身来讲,将问题在编译时暴露出来,总是比在运行时暴露出来更好解决。然而综合考虑一下架构的灵活性、程序性能等多方面的因素,或许结论会有所不同。
或许,所谓的架构,就是在不同的解决之道之间权衡、选择;实事求是。