通过派生类的构造函数将指定的参数传递给基类的带参数的构造函数,从而初始化派生类从基类继承的数据成员。派生类的构造函数使用冒号语法的参数初始化实现这种功能。
构造函数名(变元表):基类(变元表),数据成员(变元表)。。。
上面就是使用它的结构。构造函数也有一个执行顺序,首先是基类,其次是派生类。因为派生类对象的创建以基类为先决条件。可是在执行析构函数的时候却是相反的。
下面来个代码。上图
#include<iostream>
using namespace std;
class B
{
public:
B()
{cout<<"B created";}//基类先被输出
};
class A:public B
{
public:
A()
{
cout<<"A created";//派生类后输出
}
};
int main()
{
A d;
}
不过瘾?来,我们上基类数据成员进行初始化的代码
#include<iostream>
using namespace std;
class B
{
public:
int x;
B(int i):x(i){}//“:”后对应的是基类的构造函数以及对象成员对应的参数初始化
};
class A:public B
{ int a;
public:
A(int j):a(j*10),B(2)
{cout<<"B::x="<<x<<"A::a="<<a<<endl;}
};
int main()
{
A d(1);
}
如果把A(int j):a(j*10),B(2)改成A(int j)::a(j*10),B(2),那么输出的B.x=85899934,这是由于系统首先执行基类的构造函数造成的。此时,派生类的构造函数还没有执行,a也没有定义,虽然为d开辟了空间,但是没有确定初始化。上图,class A中可以看到B(2),这是对classB中的x进行了初始化,简单来书,还是上面的那个公式的应用。举例:A(int j):a(j*10),B(2)之中A是构造函数名,(int j)是变元,然后一个“:”,这个a(j*10)是数据成员(变元),B(2)这个是基类(变元),在这个代码中基类和数据成员的位置调换了,但是问题不大。
下面,我们来个继承的应用实践(大家没事就随便打代码)
#include<iostream>
using namespace std;
class A
{
public:
A(int t1,int t2)
{
x=t1;
y=t2;
}
void input()
{cout<<"x="<<x<<"y="<<y;}
protected:
int x;
int y;
};
class B:public A
{
public:
B(int t1,int t2,int t3)
:A(t1,t2)//调用基类
{redis=t3;}//对自身赋值
void output()
{A::input();//调用的基类
cout<<"redis="<<redis;}
protected:
int redis;
};
int main()
{
B b(0,0,4);
b.input();
b.output();
}
我的这个代码最简单了,老爷爷看一眼就能自己独立的打出来了,所以,你可以试一试。
接下来,我们继续讲其他的。下一个就是
多继承
一个类有多个直接基类就叫多继承。(搞基搞的多啊),多基类怎么说明?直接早派生类的后面加个“:”,不懂?好吧,我们来写一下。
class B
{
};
class B2
{
};
class C:public B1,public B2
{
}
这个和前面的继承写法几乎没差别。C就像一个混血的,它有B1,B2的成员,还有自身自带的成员。就问你骚不骚?多继承可是很牛逼的,它让c++的重用功能直接强化。它的执行顺序和单继承执行的顺寻一样,先“基”后“对”再“自身”。基类一多就容易出事,不同的基类如果有同名的成员,那么派生类对象访问它时就要加以识别。