当我们新建一个Qt的图形界面的工程时,我们可以看看它自动生成的框架代码,比如我们的主窗口名称为MainWindow,我们来看看mainwindow.cpp文件:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
}C++中类的继承与Java中的不同,C++的派生类不能继承父类的构造函数和析构函数,只能继承父类的公有成员。所以这就会造成一种结果——我们无法使用基类的构造函数来对子类进行初始化!
这里我假设大家都有Java的背景知识,没有也没关系,请听我讲。在Java中我们可以使用关键字super来直接调用父类的构造函数。比如我们定义两个类:Rectangle (矩形),Square (正方形)。从数学角度讲,正方形是一种特殊的矩形,所以我们的Square类继承自Rectangle类。在Java中像这样:
class Rectangle{
public Rectangle(int x,int y){
length = x;
width = y;
}
public void area(){
System.out.println("The area is "+length*width);
}
private int length;
private int width;
}
class Square extends Rectangle{//Java中使用extends关键字表示继承
public Square(int x) {
super(x, x);
}
}在派生类Square的构造函数中我们使用了,super这一关键字,它会默认调用基类的构造函数来初始化派生类。所以它相当于用一个整型x来初始化长方形的长和宽,所以我们得到的是一个正方形。可以验证一下,我们再使用一个类来验证这个Square是否可用,关键代码如下:
public static void main(String[] args) {
Square s = new Square(4);
s.area();
}打印结果就是 The area is 16
先依样画葫芦,写个C++版Rectangle:
class Rectangle
{
public:
Rectangle(int x,int y);
void area();
private:
int length;
int width;
};
Rectangle::Rectangle(int x, int y)
{
length = x;
width = y;
}
void Rectangle::area()
{
cout<<"The area is "<<length*width<<endl;
}派生类的声明部分,我们也可以实现;
class Square:public Rectangle
{
public:
Square(int x);
};
这只是声明了Square的构造函数,但是我们该如何实现呢?我们的C++可是没有super这一关键字的,而且C++派生类不会继承基类的构造函数。
有人说我可不可以这样:
Square::Square(int x):Rectangle
{
Rectangle::Rectangle(x,x);
}
答案当然是 NO!!。为了解决这一矛盾,C++提供了继承含参基类的实现方法,实现构造函数的方法就是这样:
Square::Square(int x):Rectangle(x,x)
{
}看懂没有,不要奇怪这个空函数体,我们所需要的初始化操作已经完成。在main函数中试试:
int main()
{
Square s(4);
s.area();
return 0;
}注意在声明部分就是和普通的继承声明是一样的,基类也不用加参。
By the Way,讲一下一个类的构造过程。
当然了,这是题外话。
我们再回过头来看看,最初的那段Qt代码:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
}现在,前面的 QMainWindow(parent) 这部分我们刚才讲完了。接下来看看后面的 ui(new Ui::MainWindow)其实这就是构造函数的初始化列表。其实理解起来要容易的多。我们的类MainWindow有一个成员ui,它是MainWindow类型(这里ui的类型和它所处的类是相同的,这是特殊的情况,我们不用计较)。举个更一般的例子。
还记得我们刚才的矩形么?我们可以使用这种方法来初始化它。
Rectangle::Rectangle(int x, int y):length(x),width(y)
{
}效果等价于刚才的:Rectangle::Rectangle(int x, int y)
{
length = x;
width = y;
}明白了吧,但是其实两种有点不同,那就是系统先调用初始化列表来初始化,接着会调用构造函数体内部的代码来初始化,也就是说,后者会覆盖掉前者。Rectangle::Rectangle(int x, int y):length(x),width(y)
{
length = 2*x;
width = 2*y;
}
然后main函数中:
int main()
{
Rectangle r(3,4);
r.area();
return 0;
}它的输出结果 是 The area is 48
从Qt谈到C++(二):继承时的含参基类与初始化列表,布布扣,bubuko.com
原文地址:http://blog.csdn.net/guodongxiaren/article/details/24885023