继承
1.继承的作用
子类从父类那里继承父类的功能和函数,可以避免代码的重写
2.继承的格式
class 子类 :public 父类
1)父类又叫基类;子类又叫派生类
2)一个子类可以继承多个父类,也可以继承多层父类
3)子类可以使用父类中的函数和成员(需是公共成员)
4)创建子类时,先执行父类的构造函数再执行自己的构造函数
#include <iostream>
using namespace std;
class Cfather
{
public:
int _fa;
Cfather() :_fa(0),_fb(0)
{
cout << "Father" << endl;
}
void show()
{
cout << "From Father" << endl;
}
private:
int _fb;
};
class Cson1 : public Cfather
{
public:
Cson1()
{
cout << "Son1" << endl;
}
};
class Cson2 : public Cfather
{
public:
Cson2()
{
cout << "Son2" << endl;
}
};
int main()
{
Cfather ob1;
Cson1 ob2;
ob2.show();
cout << ob2._fa << endl;
Cson2 ob3;
ob3.show();
cout << ob3._fa << endl;
system("pause");
return 0;
}
执行结果:
3.继承限定词(修饰符)
1)public,父类对应是什么修饰符在子类中就是什么修饰符,也就是说与父类保持一样
2)protected,父类中的public在子类中变成protected,父类中的protected在子类中变成private,private还是private
3)private,父类中的所有修饰符在子类中都变成private
4)不写限定词的话,默认为private
#include <iostream>
using namespace std;
class Cfather
{
public:
void fun1()
{
cout << "From public" << endl;
}
protected:
void fun2()
{
cout << "From protected" << endl;
}
private:
void fun3()
{
cout << "From private" << endl;
}
};
class Cson1 : public Cfather
{
};
class Cson2 : protected Cfather
{
};
class Cson3 : private Cfather
{
};
int main()
{
Cfather ob;
ob.fun1();
Cson1 ob1;
ob1.fun1();
Cson2 ob2;
ob2.fun1();
Cson3 ob3;
ob3.fun1();
system("pause");
return 0;
}
编译报错:
4.有参数的构造函数的继承
1)父类的参数从子类的初始化列表那里获取
2)父类有多个构造函数构成重载的话,根据子类的初始化列表来选择调用的父类的构造函数
3)可以用具体的数值初始化,也可以用变量传递初始化
格式:子类名():父类名(参数1,参数2)
#include <iostream>
using namespace std;
class Cfather
{
public:
int _fa;
int _fb;
Cfather(int a, int b)
{
_fa = a;
_fb = b;
}
Cfather(int a)
{
_fa = a;
}
};
class Cson : public Cfather
{
public:
Cson():Cfather(1,2)
{
cout << "From son" << endl;
cout << _fa << endl;
cout << _fb << endl;
}
};
int main()
{
Cson ob;
system("pause");
return 0;
}
执行结果:
5.析构函数与继承
析构函数的执行顺序是:先执行子类的析构函数,再执行父类的析构函数,简单来说就是从辈分低的向辈分高的执行,这与构造函数的执行顺序相反
#include <iostream>
using namespace std;
class Cfather
{
public:
Cfather()
{
cout << "From Father---构造" << endl;
}
~Cfather()
{
cout << "From Father---析构" << endl;
}
};
class Cson : public Cfather
{
public:
Cson()
{
cout << "From Son---构造" << endl;
}
~Cson()
{
cout << "From Son---析构" << endl;
}
};
int main()
{
{
Cson ob;
}
system("pause");
return 0;
}
执行结果:
6.覆盖
当子类和父类中出现同名的成员时,采用一种覆盖的方式处理
6.1数据成员同名
1)类内
子类覆盖父类,不是简单的屏蔽了父类,只是在子类中不考虑父类的命名数据成员,如果要使用父类的同名成员,则可以通过类名作用域来区分
2)类外
如果没有类名作用域则使用子类中的数据成员,如果有则使用对应的类中的数据成员
#include <iostream>
using namespace std;
class Cfather
{
public:
int _a;
Cfather()
{
_a = 10;
}
};
class Cson : public Cfather
{
public:
int _a;
Cson()
{
_a = 12;
}
void show()
{
cout << "Son of a = " << _a << endl;
cout << "Father of a = " << Cfather::_a << endl;
}
};
int main()
{
Cson ob;
ob.show();
cout << "Son of a = " << ob._a << endl;
cout << "Father of a = " << ob.Cfather::_a << endl;
system("pause");
return 0;
}
执行结果:
6.2函数同名
子类与父类中的函数同名的话与同名数据成员处理方式一样,子类的函数覆盖父类的函数,如果要区分的话,就要通过类名作用域。但是需注意的是,子类的函数与父类的函数同名但不构成重载,不管两个同名的函数参数是否不一样,都是子类的函数覆盖父类的函数
7.特殊
1)友元函数不能被继承,写在哪个类里面就是哪个类的友元
2)静态成员只有一份,不管是父类还是子类,都共享这一份静态成员