您的位置:首页 > 编程语言 > C语言/C++

C++ 继承和派生

2013-11-26 21:08 357 查看
派生

派生类是基类的具体化,而基类是派生类的抽象
派生类的定义:

class 派生类名: [继承方式] 基类名
{ 派生类新增加的成员 };

派生类中声明一个与基类成员相同的成员或者成员函数,会覆盖对应基类的成员或者成员函数

继承的方式:

(1) 公共继承(public):

公用基类成员在公用派生类中的访问属性(私有->不可访问;公用成员->公用;保护成员->保护)
对于基类私有变量只能通过基类的公用成员函数访问,比如stud1.display()。

(2) 私有继承(private):

公用基类成员在公用派生类中的访问属性(私有->不可访问;公用成员->私有;保护成员->私有),
不能访问基类的私有数据成员。对新加入的私有成员和函数,只能在派生类内部调用。

(3) 受保护的继承(protected):

公用基类成员在公用派生类中的访问属性(私有->不可访问;公用成员->保护;保护成员->保护),
不能访问基类的私有数据成员。对新加入的私有成员和函数,只能在派生类内部调用。(在内部相当于是私有的,但是在下层公用派生类中可以被访问。)

派生类的构造函数

(1) 派生类构造函数名(总参数列表) : 基类构造函数名(参数列表) {派生类中新增数据成员初始化语句},例如

Student1 (int n, string nam, char s, int a, sting ad): Student(n, nam, s) // 注意顺序
或者Student1 (int n, string nam, char s, int a, sting ad): Student(n, nam, s), age(a), addr(ad) {}

(2) 有子对象的派生类构造函数:

派生类构造函数名(总参数列表) : 基类构造函数名(参数列表), 子对象名(参数列表) {派生类中新增数据成员初始化语句}
Student1 (int n, string nam, int n1, string nam1, int a, sting ad): Student(n, nam, s), monitor(n1, nam1) {}

(3) 派生类构造函数调用顺序: 基类构造函数 -> 子对象构造函数 -> 派生类构造函数;
(4) 派生类析构函数调用顺序: 派生类析构函数 -> 子对象析构函数 -> 基类析构函数

多重继承:  

(1) class D: public A, private B, protected C {类D新增加的成员} // 调用构造函数A->B->C->D
(2) 如果基类中有同名变量,解决二义性的方式就是用当前类的名字来限定,比如Teacher::name. 对于同名函数,如果没有改变,相当于覆盖。

C继承A,B类,每个类中都含同名变量a,C c;解决二义性的方法: c.a,c.A::a,c.B::a;

(3) 多重继承引起的二义性:用基类的名来限定,C c1; c1.A::a=3; c1.A::display(); //注意一定明确变量和函数的继承关系。

虚基类:解决同名函数,节省空间,避免二义性

(1) 虚基类的一般形式:class 派生类名:virtual 继承关系 基类名
(2) 虚基类的初始化(P381):class D: public B, public C {D(int n):A(n),
B(n), C(n) {};} // A为基类,B,C为A的派生类
(3) 在派生类中不仅要负责对其直接基类进行初始化,还要负责对虚基类初始化 //编译系统只执行最后的派生类对虚基类的构造函数的调用,而忽略其他派生类的调用。

基类和派生类的转换 (只有公用派生类才是基类真正的子类型,“大材小用”原则) 

A a1; B b1; // A是基类,B是A的派生类 

(1) 派生类对象可以向基类对象赋值,例如

a1 = b1; // 单向不可逆

(2) 派生类对象可以初始化基类的引用

A &r = b1; // r并不是b1的别名,而是与b1共享一段存储单元。换句话说是b1基类部分的别名

(3) 指向基类的指针可以指向派生类

A *p = &b1; // p指向的是b1从基类继承的部分
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: