第二章继承与派生
这节课,我们来学习继承。
当从基类派生出新类时,可以对派生类作如下几个变化:
1、可以增加新的成员函数。
2、可以增加新的成员变量。
3、可以重新定义已有的成员函数。
4、可以改变现有的成员属性。
我们先来学习一个简单的派生例子
//这是一个简单的派生例子
首先,创建一个Location类
Location.h文件如下:
#include <iostream>using namespace std;class Location{private: int iPointX; public: void setPointX(int _iPointX) { iPointX = _iPointX; } void showX() { cout<<"X="<<iPointX<<endl; } };
再创建一个Rectangle类
Rectangle.h文件如下:
#include <iostream>#include "Location.h"//此处可以不写因为可以继承//using namespace std;class Rectangle:public Location{private: int iHight; public: void setHight(int _iHight) { iHight = _iHight; } void showH() { cout<<"H = "<<iHight<<endl; } };
main函数如下:
#include "Rectangle.h"int main(int argc, const char * argv[]){ Rectangle rect; rect.setPointX(10); rect.setHight(20); rect.showX(); rect.showH(); return 0;}
代码下载:http://pan.baidu.com/share/link?shareid=2883935448&uk=3189484501
访问规则
私有派生例子:
#include <iostream>
usingnamespacestd;
//程序分析:
//在这个例子中,基类的公有成员iVarA通过私有派生成了派生类的私有成员,所以当Derived类再派生其子类时,iVarA是不可访问的。
//由于私有派生这个特点,因此在实际工作中私有派生很少使用。
class Base{public:int iVarA; Base() {iVarA = 10; }};class Derived:private Base{public:int iVarC; Derived() {iVarC = 30; }void show() {cout<<iVarA<<" "<<iVarC<<endl; }};int main(int argc, constchar * argv[]){Derived derObj; derObj.show();return0;}
代码下载: http://pan.baidu.com/share/link?shareid=3533495783&uk=3189484501
保护派生
#include <iostream>using namespace std;//程序分析://在保护派生中,基类的私有和不可访问成员在派生类中是不可访问的成员在派生类中是不可访问的,基类的保护成员继续是保护的,而基类的公有成员在派生类中则变为保护的。class Base{ public: int iVarA; Base() { iVarA = 10; }};class Derived:protected Base{ public: int iVarC; Derived() { iVarC = 30; } void show() { cout<<iVarA<<" "<<iVarC<<endl; }};class Temp{ public: void tempShow() { Derived tempD; //下面这行代码报错 虽然它在Derived的父类即Base类是公有的,但Derived类通过protected继承 因此其继承来的也会变为protected 所以其他类不能直接访问 // tempD.iVarA = 10; }};int main(int argc, const char * argv[]){ Derived derObj; derObj.show(); return 0;}
下载地址:http://pan.baidu.com/share/link?shareid=792966415&uk=3189484501
多重继承例子
#include <iostream>//类C是从类A和类B中共同派生出来的。类C从类A公有派生,因此,类A的中公有函数setA和showA在类C中都是公有。//类C从类B中私有派生,所以类B中的公有函数,在类C中就是私有的。using namespace std;class A{private: int iVarA; public: void setA(int _iVarA) { iVarA = _iVarA; } void showA() { cout<<"iVarA:"<<iVarA<<endl; } };class B{ public: int iVarB; void setB(int _iVarB) { iVarB = _iVarB; } void show() { cout<<iVarB<<endl; } };class C:public A ,private B{private: int iVarC; public: void setC(int _iVarA,int _iVarB,int _iVarC) { setA(_iVarA); setB(_iVarB); iVarC = _iVarC; } void showC() { cout<<"iVarC:"<<iVarC<<endl; } };int main(int argc, const char * argv[]){ C cObj; cObj.setC(1, 2, 3); cObj.showA(); cObj.showC(); return 0;}
多重继承中构造函数和析构函数的调用顺序
#include <iostream>using namespace std;class A{protected: int iVarA; public: A(int _iVarA) { iVarA = _iVarA; cout<<"Construction A,iVarA = "<<iVarA<<endl; } ~A() { cout<<"Destorying A,iVarA="<<iVarA<<endl; } };class B:public A{private: A objA; int iVarB; public: //在派生类中对继承的基类成员的初始化,需要由派生类的构造函数调用基类的构造函数来完成,这里可以用成员初始化列表来完成,这和初始化对象成员有类似之处。 //B(派生类的参数列表):A(基类参数列表1),objA(基类参数列表2) //冒号后面的构造函数成员初始化列表,每一个基类的构造函数用逗号隔开,每项由基类名以及括号内的参数列表组成,参数列表给出所调用的构造函数以及所需的参数,如果某个类使用的是无参数或者是缺省的构造函数,则该项可以不在成员初始化列表中出现。 //当说明一个A类的对象时,首先调用基类的构造函数,对基类成员进行初始化,然后才执行派生类A自身的构造函数,如果某个基类仍然是一个派生类,则这个过程递归进行。当该对象注销时,析构函数的执行顺序和执行构造函数的顺序正好相反。 //如果派生类中还有对象成员,则对对象成员的构造函数的调用,仍然要在初始化列表中完成。 B(int _iVarB,int _iVarA,int _objA):A(_iVarA),objA(_objA) { iVarB = _iVarB; cout<<"Construction B,iVarB = "<<iVarB<<endl; } ~B() { cout<<"Destorying B, iVarB = "<<iVarB<<endl; } };int main(int argc, const char * argv[]){ // insert code here... //如果有继承,基类的构造函数最先调用。 B(1,4,5); return 0;}
代码下载地址:http://pan.baidu.com/share/link?shareid=1053220775&uk=3189484501
多重继承和双层继承
#include <iostream>using namespace std;class Base{ public: Base() { cout<<"Construction Base"<<endl; } ~Base() { cout<<"Destorying Base"<<endl; }};class A{ public: A() { cout<<"Construction A"<<endl; } ~A() { cout<<"Destorying A"<<endl; }};class B:public Base{ public: B() { cout<<"Construction B"<<endl; } ~B() { cout<<"Destorying B"<<endl; }};class C{ public: C() { cout<<"Construction C"<<endl; } ~C() { cout<<"Destorying C"<<endl; }};class Object:public A ,public B , public C{ public: Object() { cout<<"Construction Object"<<endl; } ~Object() { cout<<"Destorying Object"<<endl; }};//在多重继承中先执行最先继承的对象 例如:本例中的A//在双继承中例如本例中的B类 B类是继承自 Base 所以会先执行Base//在析构函数的执行顺序与构造函数的执行顺序相反int main(int argc, const char * argv[]){ // insert code here... Object obj; return 0;}
代码下载: http://pan.baidu.com/share/link?shareid=1098289671&uk=3189484501
多重继承中的二义性
#include <iostream>using namespace std;class A{ public: void Show() { cout<<"A"<<endl; }};class B{ public: void Show() { cout<<"B"<<endl; } void Print() { cout<<"Print()B"<<endl; }};//多重继承是指同时继承多个,例如如下:class Object:public A,public B{ public: void Print() { cout<<"ObjectA||B"<<endl; } void ObjectShowA() { A::Show(); } void ObjectShowB() { B::Show(); }};//如果一个类是由两个以上的类派生出来的,那么对基类成员的访问必须是无二以性的。但是如果基类中含有相同名称的成员,则访问时可能产生二义性。int main(int argc, const char * argv[]){ Object obj; //下面注释的这种写法会报错因为会存在二义性 // obj.Show(); obj.A::Show(); obj.Print(); obj.B::Show(); return 0;}
代码下载: http://pan.baidu.com/share/link?shareid=1143818360&uk=3189484501
多层继承的二义性
#include <iostream>using namespace std;//多层继承: 如果一个派生类从多个基类中派生,并且这些基类又有一个共同的基类,则在这个派生类中访问这个共同的基类中的成员时可能出现二义性。class Base{ public: int iBaseData; };class A:public Base{ public: int iAData;};class B:public Base{ public: int iBData;};class Object:public A,public B{ public: int iObjectData;};int main(int argc, const char * argv[]){ Object obj; obj.A::iBaseData = 10; obj.B::iBaseData = 20; cout<<"obj.A::iBaseData = "<<obj.A::iBaseData<<endl; cout<<"obj.B::iBData = "<<obj.B::iBaseData<<endl; return 0;}
代码下载: http://pan.baidu.com/share/link?shareid=1208687701&uk=3189484501
虚基类
#include <iostream>using namespace std;//很显然当出现上节中的两层继承时,程序可能会出现二义性,如果能使这个公共基类只产生一个成员实例的话,很显然就可以解决这个二义性的问题了,这时我们可以将这个基类说明虚基类的方式来解决这个问题,这就要求在Base类派生新类时,使用关键字virtual将Base类说明为虚基类class Base{ public: int iBaseData; void Print() { cout<<"iBaseData = " << iBaseData<<endl; }};class A:virtual public Base{ public: int iAData; void Print() { cout<<"In A iBaseData"<<iBaseData<<endl; }};class B:virtual public Base{ public: int iBate; void Print() { cout<<"In B iBaseData = "<<iBaseData<<endl; } };class Object:public A , public B{ public: int iObjectData; void Print() { cout<<"In Object iBaseData = "<<iBaseData<<endl; }};//虚拟类可以使多层继承中公共基类只产生一个实例,即在类Object中,Base类只有一个实例。//这时obj.A::iBaseData == obj.B::iBaseData == obj.Object::iBaseDataint main(int argc, const char * argv[]){ Object obj; obj.iBaseData = 1000; obj.A::Print(); obj.B::Print(); obj.Base::Print(); obj.Print(); //继承的几点总结://能用组合则不用继承//继承的层数小于等于4层。//尽量避免使用多重继承 return 0;}
代码下载: http://pan.baidu.com/share/link?shareid=1294366574&uk=3189484501
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。