51、如果软件除了问题(Bug ),如何快速定位?主要方法有哪些?
打印输出/代码调试/日志记录/分析工具/找同事讨论。
-
二分法定位技巧
无论是有多复杂的代码,利用二分法定位技巧一般都是可以定位到问题所在。从二分法定位技巧可以延伸出一些具体的处理bug的方法,比如:对输入数据二分、对代码版本二分、注释掉部分代码、在不同位置插入试探性代码、对运行环境二分。 -
IDE调试
IDE的VS debug的功能简直就是立竿见影。它可以加断点,单步调试。
单步调试可以让我们对代码逻辑,执行顺序,以及各种中间结果更加清晰。
至于本身容易出错的BUG,用IDE调试简直是再合适不过了。 -
重新读一遍程序
相对新手程序员来说,如果代码出现bug,可以重新读一遍程序。这种方法是最有效、最快速的Debug方式。 -
重写一遍
如果你发现无论如何也找不到BUG,而且代码只是复杂,本身不是很长,直接重写代码吧!
52、引用和指针有何区别
- 指针是一个对象,而引用仅是一个对象的别名
- 引用使用时无需解引用,指针需要
- 引用只能在定义时初始化一次,而指针可变
- 引用不能为空,指针可以为空
- 有多级指针没有多级引用
- 不会为引用变量开辟内存空间,它和它引用的变量共用一块内存空间,指针会开辟内存空间
- 引用自加改变引用值的内容,指针自加改变指针的指向
- sizeof含义不同,引用结果为引用类型的大小,指针始终是地址空间所占大小
- 引用比指针使用起来相对更安全
53、什么情况下使用虚函数? 和纯虚函数有什么区别? 虚析构函数的作用是什么?
虚函数的主要作用是"运行时多态"。虚析构函数的作用在于使用delete删除一个对象时,能确保析构函数被正确的执行。区别:
-
虚函数和纯虚函数可以定义在固一个类(class)中,含有纯虚函数的类被称为抽象类(abstractclass),而只含有虚函数的类(class)不能被称为抽象类(abstract class)。
-
虚函数可以被直接使用,也可以被子类(sub class)重载以后以多态的形式调用,而纯虚函数必须在子类(sub class)中实现该函数才可以使用,因为纯虚函数在基类(base class)只有声明而没有定义。
-
虚函数和纯虚函数都可以在子类(sub class)中被重载,以多态的形式被调用。
-
虚函数和纯虚函数通常存在于抽象基类(abstract base class -ABC)之中,被继承的子类重载,目的是提供一个统一的接口。
-
虚函数的定义形式:virtual {method body}
纯虚函数的定义形式: virtual { }= 0;
在虚函数和纯虚函数的定义中不能有static标识符,原因很简单,被static修饰的函数在编译时候要求前期bind,然而虚函数却是动态绑定(run-time bind),而且被两者修饰的函数生命周期(life recycle)也不一样。 -
虚函数必须实现,如果不实现,编译器将报错。
-
对于虚函数来说,父类和子类都有各自的版本。由多态方式调用的时候动态绑定。
-
实现了纯虚函数的子类,该纯虚函数在子类中就编程了虚函数,子类的子类即孙子类可以覆盖该虚函数,由多态方式调用的时候动态绑定。
-
虚函数是C++中用于实现多态(polymorphism)的机制。核心理念就是通过基类访问派生类定义的函数。
-
多态性指相同对象收到不同消息或不同对象收到相同消息时产生不同的实现动作。C++支持两种多态性∶编译时多态性,运行时多态性。
- a.编译时多态性:通过重载函数实现
- b.运行时多态性:通过虚函数实现.
-
如果一个类中含有纯虚函数,那么任何试图对该类进行实例化的语句都将导致错误的产生,因为抽象基类(ABC)是不能被直接调用的。必须被子类继承重载以后,根据要求调用其子类的方法。
54、对Qt元对象系统了解吗?
Qt对标准的C++进行了扩展,如信号槽、对象属性等。Qt的元对象编译系统MOC是一个预处理器,当Qt读取源文件时检测到类中包含有Q_OBJECT宏时,则会创建一个新的文件(生成路径下的moc开头的文件),将源码转换为C++编译器可以识别的代码写入moc开头的文件,然后C++编译器对其进行编译。 当你的类需要使用Qt的扩展功能时,如信号槽、对象属性等时,则必须使用MOC,反之如果你的类不使用这些功能的时候不要无畏的使用MOC增大源码体积。 使用MOC系统的方法︰
- 继承QObject。
- 类中添加Q_OBJECT宏。
55、Qt中的MVD了解吗?
Qt的MND包含三个部分Model(模型); View(视图); 代理(Delegate)。Model否则保存数据,View负责展示数据,Delegate负责ltem样式绘制或处理输入。这三部分通过信号槽来进行通信,当Model中数据发生变化时将会发送信号到View,在View中编辑数据时,Delegate负责将编辑状态发送给Model层。基类分别为QAbstractItemModel、QAbstractltemView、QAbstractltemDelegate。Qt中提供了默认实现的MVD类,如QTableWidget、QListWidget、QTreeWidget等.
56、QObject是否是线程安全的
QObject及其所有子类都不是线程安全的(但都是可重入的)。因此,你不能有两个线程同时访问一个QObject对象,除非这个对象的内部数据都已经很好地序列化(例如为每个数据访问加锁)。
57、QObject的线程依附性是否可以改变
调用QObject::moveToThread()函数。该函数会改变一个对象及其所有子对象的线程依附性。
由于QObject本身是线程不安全的,因此moveToThread接口的调用必须在QObject对象所在的线程内调用。
58、QFrame与QWidget的区别
QFrame和QWidget都是Qt中的GUI组件,但是它们有一些区别:
- 继承关系∶QFrame继承自QWidget,所以QFrame具有QWidget的所有功能。
- 功能 :QFrame提供了一个简单的框架 ,可以作为其他控件的容器。 它还可以用来绘制简单的图形,如线条。QWidget没有这样的功能,但是提供了基础的GUI组件功能,如设置尺寸和位置等。
- 外观∶QFrame可以有边框和背景颜色,因此外观更加丰富。QWidget只有背景颜色,没有边框。通常,当需要一个简单的框架时使用QFrame,当需要基础的GUI组件功能时使用QWidget。
59、信号重载了,如何确定连接哪个信号?
采用函数指针确定连接哪个信号。
60、槽函数的参数可以少于信号的参数吗?
- 槽函数本身参数比信号的少
- 槽函数可以参数带有默认参数