继承与派生
1、概念:通过保持基类的特性,改造原有成员或者增加新的成员的方式,从一个基类获得新的类,这种方式成为继承或者派生。
内涵:继承是指对基类的特性和成员的保持;派生是指在基类的基础上增加新的成员或者特性。
继承和派生的主要方式有:public/protected/private
语法:
class DISPLAY
{
public:
void display()
{
std::cout << "DISPLAY" << std::endl;
}
};
class BASE1 :public DISPLAY
{
public:
void display()
{
std::cout << "BASE1" << std::endl;
}
};
2、继承的主要方式与内涵
不同继承方式主要的影响包括:a.派生类成员对基类成员的访问权限不同;b.派生类对象对基类成员的访问权限不同。
公有继承的访问控制:基类的public和protected成员被继承过来以后仍然是public和protected;基类的private成员不允许直接访问;
访问权限:派生类中的成员可以访问基类的public和protected成员,不允许访问基类的private成员;派生类对象可以访问public成员。
3、基类和派生类之间的类型转换
不要重复定义继承而来的非虚函数!!!!
#include <iostream>
class DISPLAY
{
public:
void display()
{
std::cout << "DISPLAY" << std::endl;
}
};
class BASE1 :public DISPLAY
{
public:
void display()
{
std::cout << "BASE1" << std::endl;
}
};
class BASE2 :public BASE1
{
public:
void display()
{
std::cout << "BASE2" << std::endl;
}
};
void display(DISPLAY &ptr)
{
ptr.display();
}
int main()
{
DISPLAY A;
BASE1 B;
BASE2 C;
display(A);
display(B);
display(C);
return 0;
}
4、派生类的构造函数与析构函数
C++11以前,派生类不能够继承基类的构造函数,这时,派生类的需要定义自己的构造函数对继承过来的成员与新增成员进行初始化。
单继承时,其语法如下:
类名::构造函数名(基类所需的形参,派生类新增成员所需形参):
基类名(参数表),新增成员初始化列表。
{ //其他初始化 };
多继承时,语法如下:
类名::构造函数名:(基类所需的形参,派生类新增成员所需形参):
基类名1(参数表),
基类名2(参数表),
基类名3(参数表),
新增成员初始化列表
若派生类中还有其他类对象成员怎么办?
类名::构造函数名:(基类所需的形参,派生类新增成员所需形参):
基类名1(参数表),... ,基类名n(参数表),
新增成员初始化列表(将对象成员包含在内)
{ //其他初始化 };
#include <iostream>
class DISPLAY
{
public:
DISPLAY(int a);
~DISPLAY();
private:
int i;
};
DISPLAY::DISPLAY(int a):i(a)
{
std::cout << "DISPLAY" << std::endl;
}
DISPLAY::~DISPLAY() {}
class BASE1 :public DISPLAY
{
public:
BASE1(int a,int b);
~BASE1() {};
private:
int i;
};
BASE1::BASE1(int a, int b) :DISPLAY(a), i(b)
{
std::cout << "BASE1" << std::endl;
}
class BASE2 :public BASE1
{
public:
BASE2(int a, int b,int c);
~BASE2() {};
private:
int i;
};
BASE2::BASE2(int a, int b, int c): BASE1(a,b), i(c)
{
std::cout << "BASE2" << std::endl;
}
int main()
{
DISPLAY A(1);
BASE1 B(2,3);
BASE2 C(1, 2, 3);
return 0;
}
如果不需要初始化基类成员,同时基类有默认构造函数,构造派生类对象时可以不向基类成员传递参数。相反,若想要初始化基类成员,同时基类有自定义构造函数,那么在构造派生类时需要向基类传递参数。
构造函数的执行次序
从样例程序可以看出,派生类构造函数在执行时,根据被继承的基类的声明次序调用各自的构造函数进行成员初始化。成员的初始化顺序是按照成员在类中的定义次序进行的,跟其在构造函数初始化列表中的先后次序无关。
5、派生类成员访问与类名限定
对派生类中和基类同名的成员的访问,要注意:派生类对象或者引用通过“::”操作符可以访问派生类中的相应成员,但是无法通过同样的方式访问基类中的同名成员。访问基类中的同名成员时,要使用“.”来指定要访问的基类