概述:
c++最重要的特征是代码重用
,通过继承机制可以利用已有的数据类型来定义新的 数据类型,新的类不仅拥有旧类的成员,还拥有新定义的成员。 一个 B 类继承于 A 类,或称从类 A 派生类 B。这样的话,类 A 成为基类(父类), 类 B 成为派生 类(子类)。 派生类中的成员,包含两大部分: 一类是从基类继承过来的,一类 是自己增加的成员。 从基类继承过过来的表现其共性,而新增的成员体现了其个 性。
继承机制允许程序员在保持原有的特性基础上进行扩展,增加功能,这样产生新的类,称作是派生类。继承呈现了面向对象程序设计的层析结构,体现了由简单到复杂的认知过程。继承是类设计层次的复用。
派生类的定义
Class 派生类名 : 继承方式 基类名
{
//派生类新增的数据成员和成员函数
}
继承方式有三种:
对应的权限特点以下举例:
注:派生类继承基类,派生类拥有基类中全部成员变量和成员方法(除了构造和析构之 外的成员方法),但是在派生类中,继承的成员并不一定能直接访问,这是由于不同的继承 方式导致不同的访问权限。
继承中的构造和析构函数:
继承中的构造和析构 子类对象在创建时会首先调用父类的构造函数 父类构造函 数执行完毕后,才会调用子类的构造函数 当父类构造函数有参数时,需要在子类 初始化列表(参数列表)中显示调用父类构造函数 析构函数调用顺序和构造函数相 反
简单的代码实现:
#include <stdio.h>
#include <iostream>
#include <string>
using namespace std;
class Base
{
public:
Base()
{
cout << "构造函数调用" <<endl;
}
~Base()
{
cout << "析构函数调用" << endl;
}
public:
int a;
int c;
};
class test : public Base
{
public:
test()
{
cout << "派生类的构造函数调用" <<endl;
}
~test()
{
cout << "派生类的析构函数调用" <<endl;
}
int b;
};
void test01()
{
test t1;
t1.a = 10;
t1.b = 100;
}
int main(int argc, char *argv[])
{
test01();
return 0;
}
程序结果如下:
所以继承中的构造函数和析构函数调用顺序如下:
子类调用父类的有参构造:
基类有如下有参构造:
Base(int a)
{
this->a = a;
cout << "基类的构造函数调用" << endl;
}
派生类若想调用基类的有参构造必须要用到初始化列表
test(int a ,int b) : Base(a),b(a);
{
cout << "派生类的构造函数调用" << endl;
}
继承中同名成员的处理方法:
概述:继承的时候有可能会出现基类和派生类新增的成员变量和成员函数有相同的名字,所以叫同名成员简单的代码如下:
#include <stdio.h>
#include <iostream>
#include <string>
using namespace std;
class Base
{
public:
Base()
{
a = 100;
cout << "构造函数调用" <<endl;
}
~Base()
{
cout << "析构函数调用" << endl;
}
public:
int a;
void print()
{
cout << "Base class function!" <<endl;
}
};
class test : public Base
{
public:
test()
{
a = 999;
cout << "派生类的构造函数调用" <<endl;
}
~test()
{
cout << "派生类的析构函数调用" <<endl;
}
void print()
{
cout << "test class function!"<<endl;
}
int a;
};
void test01()
{
test t1;
cout << t1.a << endl;
t1.print();
}
int main(int argc, char *argv[])
{
test01();
return 0;
}
执行结果如下:
由上述程序结果可知:
当子类成员和父类成员同名时,子类依然从父类继承同名成员 如果子类有成员和 父类同名,子类访问其成员默认访问子类的成员(本作用域,就近原则) 在子类通 过作用域::进行同名成员区分(在派生类中使用基类的同名成员,显示使用类名限定 符),也就是说基类和派生类成员名相同的时候,默认会调用和使用子类的成员变量和函数,但是如果在访问的时候加上作用域比如:
test t1;
cout << t1.Base::a << endl;
t1.Base::print();
最后会去调用基类的成员变量和函数
非自动继承的函数
不是所有的函数都能自动从基类继承到派生类中。构造函数和析构函数用来处理对 象的创建和析构操作,构造和析构函数只知道对它们的特定层次的对象做什么,也 就是说构造函数和析构函数不能被继承,必须为每一个特定的派生类分别创建。 另外 operator=
也不能被继承,因为它完成类似构造函数的行为。也就是说尽管我 们知道如何由=右边的对象如何初始化=左边的对象的所有成员,但是这个并不意 味着对其派生类依然有效。 在继承的过程中,如果没有创建这些函数,编译器会 自动生成它们。
继承中的静态成员特性
基类中静态变量:
对于静态变量来说,基类及其所有子类公用基类的静态变量;
基类中静态函数:
静态函数和普通函数继承的区别:
1,他们都可以被继承到派生类中。
2. 如果重新定义一个静态成员函数,所有在基类中的其他重载函数会被隐藏。
3. 如果我们改变基类中一个函数的特征,所有使用该函数名的基类版本都会被隐藏。