在Qt新建继承Qt类的类后,经常会在构造函数看到parent的参数的初始化。如:
DialogRangeReference.h
class DialogRangeReference : public QDialog
{
Q_OBJECT
public:
explicit DialogRangeReference(QWidget *parent = 0);
……
private:
Ui::DialogRangeReference *ui;
}
DialogRangerReference.cpp
DialogRangeReference::DialogRangeReference(QWidget *parent) :
QDialog(parent),
ui(new Ui::DialogRangeReference)
{
……
}
以上面的代码为例,可以发现DialogRangeReference
是QDialog
的子类。ui
是DialogRangeReference
的成员。ui(new Ui::DialogRangeReference)
是初始化ui
,这里new出一个对象赋值给ui
。
而在构造函数定义中QDialog(parent)
会比较晦涩。这里需要结合继承于QDialog
来说,QDialog
是DialogRangeReference
的父类,并且DialogRangerReference
的构造函数带参数QWidget *parent
,因此这里的其实是调用了父类的构造函数,并将参数parent
传给了父类的构造函数。在执行DialogRangeReference
的构造函数前,先调用父类QDialog
的构造函数。由于这里是调用,而不是赋初值,因此这里的写法与ui
是有区别的。
QWidget
是因为QWidget
为窗口类的基类;QObject
则是非窗口类的基类;parent
可以指定此类的父类,当父类delete时,Qt可以保证所有子类都会被正确的delete掉,能够帮助开发人员管理一部分内存;parent
则指定了组件的父组件。这对于一个对话框来说是比较合适的,因为对话框一般不作为顶层容器出现。因此任务栏上不会有对话框的位置。如果对话框不指定parent
,则对话框会作为顶层容器出现。父类Student.h如下:
#include
#include
using namespace std;
class Student
{
public:
Student(int n,string nam,char s) {
num=n;
name=nam;
sex=s;
}
~Student(){}
protected:
int num;
string name;
char sex;
};
子类Student1.h如下:
class Student1:public Student
{
Student1(int n,string nam,char s,int a,string ad):Student(n,nam,s) {
age=a;
addr=ad;
}
void show(){}
private:
int age;
string addr;
};
main.cpp如下:
int main()
{
Student1 stud1(10010,"Wang",'f',19,"BeiJing Road,Shanghai");
......
}
派生子类会继承基类的所有成员,除了构造函数和析构函数(派生子类会调用父类的无参数构造函数,是调用,而不是继承)。因此,子类从父类继承过来的成员变量,若不想自己写构造函数初始化时,就只能先初始化父类中的成员变量,然后再继承过来。
从上面代码中可以看出,子类Student1中的构造方法只有对新增成员int age和string addr的初始化操作,对于从父类继承过来的成员num,name,sex无初始化语句,但子类又不能继承父类的构造方法,要么就另外再写一个初始化语句,可这样操作就造成了重复性语句。此时就得通过Student1(int n,string nam,char s,int a,string ad):Student(n,nam,s){age=a;addr=ad;}
先初始化父类成员变量,从而间接初始化子类从父类继承过来的成员变量。
请注意派生子类构造函数首行的写法:
Student1(int n,string nam,char s,int a,string ad):Student(n,nam,s)
其一般形式为:
派生类构造函数名(总参数列表):基类构造函数名(参数列表)
{
派生类中新增数据成员初始化语句;
}
冒号前面的部分是派生类构造函数的主干,它的总参数表列中包括基类构造函数所需的参数和对派生类新增的数据成员初始化所需的参数。冒号后面的部分是要调用的基类构造函数及其参数。
基类构造函数后面括号内的参数表列中只有参数但无参数类型,因为在这里不是定义基类构造函数,而是调用基类构造函数,因此这些参数是实参而不是形参。他们可以是常量、全局变量和派生类构造函数总参数表中的参数。
从上面代码可以看到,在main函数中,建立对象stud1时,有5个参数,其中前3个是用来传递基类构造函数的,后2个用来对派生子类所增加的数据成员初始化。
以上例子中,调用基类构造函数时的实参是从子类构造函数的总参数表中获得的,也可以不从那传递,直接使用常量或全局变量,如:Student1(string nam,char s,int a,string ad):Student(10010,nam,s)
;这样父类的n默认初始化为10010,子类直接把n=10010继承过来,因此不用写。