1 / 56

第四章 派生类与继承

1. 第四章 派生类与继承. 2. 继承. 昆 虫. 派生. 有 翅 类. 无 翅 类. 蛾. 蝴蝶. 苍蝇. 单一继承. 窗 口. 滚 动 条. 可滚动的窗口. 多重继承. 4.1 派生类的概念. 4.1.1 为什么要使用继承 从现有类出发建立新的类,使新类继承老类的特点和功能,并且又加上自己的特点和功能的程序设计方法,是面向对象程序设计一个重要的技术。 老的类叫 基类 ,新的类叫 派生类 。 对派生类可做如下几种变化: (1) 可以增加新的成员数据。 (2) 可以增加新的成员函数。

paulos
Download Presentation

第四章 派生类与继承

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 1 第四章 派生类与继承

  2. 2 继承 昆 虫 派生 有 翅 类 无 翅 类 蛾 蝴蝶 苍蝇 单一继承 窗 口 滚 动 条 可滚动的窗口 多重继承 4.1 派生类的概念 4.1.1 为什么要使用继承 从现有类出发建立新的类,使新类继承老类的特点和功能,并且又加上自己的特点和功能的程序设计方法,是面向对象程序设计一个重要的技术。 老的类叫基类,新的类叫派生类。 对派生类可做如下几种变化: (1) 可以增加新的成员数据。 (2) 可以增加新的成员函数。 (3) 可以重新定义己有的成员函数。 (4) 可以改变现有成员的属性。 C++中有两种继承: 单一继承和多重继承。 对于单一继承 派生类只能有一个基类; 对于多重继承 派生类可以有多个基类。

  3. 3 class employee{ private: char name[10]; int age; char sex; char department[20]; float salary; public: void print(); }; 4.1.1为什么要使用继承? class person{ private: char name[10]; int age; char sex; public: void print(); }; 比较二个类

  4. 4 声明派生类: class 派生类名 : 派生方式 基类名 { //派生类新增的数据成员和函数成员 }; 4.1.2 派生类的声明 基类: class 类名 { 类的内容 }; 派生方式可为公有派生(用public)和私有派生(用private或缺省)。 class person{ private: char name[10]; int age; char sex; public: void print(); }; class employee : public person { private: char department[20]; float salary; public: void print(); };

  5. 5 1. 私有派生 void main() { derived obj; obj.setxy(10,20); obj.showxy(); } (1) 私有派生类对基类成员的访问 基类的公有成员相当于派生类的私有成员,派生类的成员数可以访问它。但基类的私有成员派生类的成员函数不可以访问它。 例4.1 #include <iostream.h> class base{ //定义基类 int x; public: void setx(int n) { x=n; } void showx() { cout << x << endl; } }; class derived : private base { //定义私有派生类 int y; public: void setxy(int n, int m) { setx(n); y=m; } void showxy() { cout << x << y << endl; } // 非法 不能访问 x ,改为 showx() };

  6. 6 (2) 外部函数(main)对私有派生类继承来的成员的访问 void main() { derived obj; obj.setx(10); //出错 obj.sety(20); //合法 obj.showx(); //出错 obj.showy(); //合法 } 私有派生时,基类的所有成员在派生类中都成为私有成员,外部函数不能访问。 例4.2 #include <iostream.h> class base{ //定义基类 int x; public: void setx(int n) { x=n; } void showx() { cout << x << endl; } }; class derived : private base { //定义私有派生类 int y; public: void sety(int n) { y=n; } void showy() { cout << y << endl; } };

  7. 7 2. 公有派生 在公有派生中,基类的私有成员对派生类来说仍是基类的私有成员,只能通过基类的公有成员函数访问(相当于可访问性保持不变),不允许外部函数和派生类的成员函数直接访问。基类中的公有成员相当于派生类的公有成员,外部函数和派生类的成员函数可直接访问。 例4.3 #include <iostream.h> class base{ //定义基类 int x; public: void setx(int n) { x=n; } void showx() { cout << x << endl; } }; class derived : public base {//定义公有派生类 int y; public: void sety(int n) { y=n; } void showy() { cout << y << endl; } }; void main() { derived obj; obj.setx(10); //合法 obj.sety(20); //合法 obj.showx(); //合法 obj.showy(); //合法 }

  8. 8 在作类派生时,可能导致几个类使用同一函数名或变量名,这就会产生二义性。 #include <iostream.h> void main( ) { X a; Y b; int i=a.f(); int j=b.f(); cout << "i=" << i << endl; cout << "j=" << j << endl; } 如 class X { public: int f(); }; class Y : public X { public: int f(); int g(); }; 这里 b.f() 用的是 Y 类的 f() 还是 X 类的 f()? 用的是 Y 类的 f(),编译器会自动从继承底向上搜索,这叫作支配规则。如果一定要用 X 类的 f(),则可写成 b.X::f(); X::叫作用域分辨符。

  9. 9 表4.1公有派生和私有派生的访问特性

  10. 10 4.1.3 基类的保护成员作用 无论私有派生还是公有派生,派生类无权访问它的基类的私有成员。派生类要想访问它的基类的私有成员,只能通过调用基类的成员函数的方式实现,对这有时会带来不便。C++还提供一种访问属性 protected 保护性成员。基类的保护成员具有私有成员和公有成员双重角色:对自已的对象而言它是私有成员,即不能被其他程序或函数访问(只能被类中的成员函数访问);而对派生类而言,它又相当于是基类的公有成员。当公有派生时,基类的保护成员在派生类也为保护成员。当私有派生时,相当于派生类的私有成员,派生类的成员函数可以访问它。

  11. 例4.4 保护成员的例子 #include <iostream.h> class samp{ int a; protected: int b; public: int c; samp(int n, int m ) { a=n; b=m; } //构造函数 int geta() { return a; } int getb() { return b; } }; void main () { samp obj(20,30); obj.a=88; //非法,类的私有成员不能对外 obj.b=99; //非法,类的保护成员相当于私有成员不能对外 obj.c=50 //合法,类的公有成员能对外 cout << obj.geta() << ' '; cout << obj.getb() << ' ' <<obj.c<<endl; } 11

  12. 12 例4.5 保护成员被公有派生后的例子 #include <iostream.h> class base { protected: int a,b; //保护成员 public: void setab(int n, int m) { a=n; b=m; } }; class derive:public base { int c; public: void setc(int n) { c=n; } void showabc()//a,b 相当于派生类的私有成员,成员函数可访问 { cout <<a<<' '<<b<<' '<<c<<endl; } }; void main() { derive obj; obj.setab(2,4); //基类的公有成员相当于派生类的公有成员,可被外界访问 obj.setc(3); obj.showabc(); }

  13. 13 例4.6 保护成员被私有派生后的例子 class derive1:private base { protected: int b; public: void setb(int sb) { b=sb; } }; #include <iostream.h> class base { protected: int a; //保护成员 public: void seta(int sa) { a=sa; } }; class derive2:public derive1 { int c; public: void setc(int sc) { c=sc; } void show() { cout<<"a="<<a<<endl; //非法,保护成员 a 被derive1私有派生后 成为derive1的私有成员,dervie2中不能//直接访问 cout<<“b=”<<b<<endl; //合法 cout<<“c=”<<c<<endl; } //合法 }; void main() { base op1; op1.seta(1); derive1 op2; op2.setb(2); derive2 op3; op3.setc(3); op3.show(); }

  14. 14 表4.2 基类成员在派生类中和外部函数中的访问权限

  15. 15 保护成员的这种性质还可传播给派生的派生。 例 保护成员的性质传播给派生的派生的例子。 class Base { int value; protected: void SetValue(int v) { value=v; } }; class First : public Base { int total; public: void SetTotal(int t) { total=t; SetValue(t); //使用基类的保护成员,相当于本类的保护成员 } }; class Second : public First { int count; public: void SetCount(int c) { count=c; SetValue(c); //使用基类的保护成员,相当于本类的保护成员 } };

  16. 16 4.2 派生类的构造函数和析构函数 当一个派生类有构造函数时,则它必须对自己的数据成员和继承而来的基类数据成员初始化,这和前面(第三章)讲的类定义中有对象作为数据成员类似。因此需要由派生类的构造函数调用基类的构造函数来完成。

  17. 17 4.2.1 派生类的构造函数和析构函数执行顺序 void main( ) { dervie op; } 当创建派生类对象时,首先执行基类的构造函数,随后再执行派生类的构造函数;当撤消派生类对象时,则先执行派生类的析构函数,随后再执行基类的析构函数。 例4.7 #include <iostream.h> class base { public : base( ) { cout << "执行 base 类的构造函数\n"; } ~base( ) { cout <<"执行 base 类的析构函数\n"; } }; class derive:public base { public : dervie( ):base( ) { cout << "执行 dervie 类的构造函数\n"; } ~dervie( ) { cout <<"执行 dervie 类的析构函数\n"; } };

  18. 18 4.2.2 派生类的构造函数和析构函数的定义规则 void main( ) { derive obj(30,40); obj.showi( ); obj.showj( ); } 当派生类的基类构造函数含有参数时,必须定义派生类的构造函数。格式为: 派生类的构造函数名(参数表):基类的构造函数名(参数表) { //...... } 其中,基类构造函数参数,来源于派生类的构造函数的参数表。 例4.8 #include <iostream.h> class base { int i; public: base(int n) //基类的构造函数 { cout << "执行 base 基类的构造函数\n"; i=n; } ~base( ) { cout <<"执行 base 基类的析构函数\n"; } void showi( ) { cout << i << endl; } }; class derive:public base { int j; public : dervie(int n, int m):base(m) //派生类的构造函数 { cout << "执行 dervie 派生类的构造函数\n"; j=n; } ~dervie( ) { cout <<"执行 dervie 派生类的析构函数\n"; } void showj( ) { cout << j << endl; } };

  19. 19 当派生类中还含有对象成员时,其构造函数的格式为: 派生类的构造函数名(参数表):基类的构造函数名(参数表),对象成员1(参数表),..., 对象成员n(参数表) { //...... } 定义派生类对象时构造函数执行顺序: 基类的构造函数 对象成员构造函数 派生类的构造函数; 当撤消派生类对象时,析构函数执行顺序正好相反。 例4.9#include <iostream.h> class base { int x; public: base(int i) //基类的构造函数 { cout << "执行 base 基类的构造函数\n"; x=i; } ~base() { cout <<"执行 base 基类的析构函数\n"; } void show() { cout << "x=" << x << endl; } }; class derive:public base { base d; public : dervie(int i):base(i),d(i) //派生类的构造函数 { cout << "执行 dervie 派生类的构造函数\n"; } ~dervie() { cout <<"执行 dervie 派生类的析构函数\n"; } }; void main() { derive obj(5); obj.show(); } 说明 P-105

  20. 20 4.3 多重继承 从多个类派生出一个类,也即一个类从多个基类继承称为多继承。 4.3.1 多重继承的声明 多重继承的声明格式如下: class 派生类名: 派生方式1 基类名1, ... , 派生方式n 基类名n { //派生类新增的数据成员和函数成员 }; 派生类继承了基类1 到 基类n的所有数据成员和函数成员,其访问权限规则与单继承情况一样,多继承可看成单一继承的扩展。 例4.10 #include <iostream.h> class X { int a; public: void setX(int x) { a=x; } void showX() { cout <<"a="<<a<<endl; } }; class Y { int b; public: void setY(int x) { b=x; } void showY() { cout <<"b="<<b<<endl; } };

  21. 21 class Z: public X, private Y { int c; public: void setZ(int x, int y) { c=x; setY(y); } void showZ() { showY(); cout<<"c="<<c<<endl; } // void setZ(int x, int y, int z) { a=x; setY(y); c=z; } // void showZabc() { cout<<"a="<<a<<endl; // showY(); cout<<"c="<<c<<endl; } }; void main() { Z obj; obj.setX(3); obj.showX(); obj.setY(4); //错误 obj.showY(); //错误 obj.setZ(6,8); obj.showZ(); // obj.setZ(1,2,3); // obj.showZabc(); }

  22. 22 再讲一个例 class C:public A, private B { private: int c; public: void setC(int, int); void showC( ); }; class A { private: int a; public: void setA(int); void showA( ); }; class B { private: int b; public: void setB(int); void showB( ); }; A类的公有成员(和保护成员) C类中仍是公有的(保护的) B类所有成员 C类中是私有的。

  23. 23 完整的程序如下: #include <iostream.h> class A { private: int a; public: void setA(int x){ a=x; } void showA(){ cout << a <<endl; } }; class B { private: int b; public: void setB(int x){ b=x; } void showB(){ cout << b <<endl; } };

  24. class C:public A, private B { private: int c; public: void setC(int x, int y) { c=x; setB(y); } void showC( ) { showB( ); cout<< c <<endl; } }; 24 void main() { C obj; obj.setA(3); obj.showA(); obj.setB(5); //错误 obj.showB(); //错误 obj.setC(5,8); obj.showC(); }

  25. 25 真正生产二义性的情况是,一个派生类从多个基类派生,而这些基类又有一个相同的 基类,则在派生类访问这个共同基类的成员时会产生二义性。 class A { public: void fun() ; }; class B { public: void fun() ; void gun() ; }; class C: public A, public B { void gun() ; void hun() ; } 若有对象 C obj ; obj.fun() 是使用 A 类的 fun() 呢? 也是 B 类的 fun()? 编译器无法自动确定,因为对 C 类来说 A 类和 B 类是同一级,我们可以用成员名限定(作用域分辨操作符)来人为的消去二义性。 obj.A::fun(); obj.B::fun();

  26. 26 4.3.2 多重继承的构造函数和析构函数 设类Y从X1,X2,....Xn类派生(当只有一个X1时为单继承,否则为多继承),则派生类Y的构造函数Y的一般形式为: Y::Y(参数表0):X1(参数表1),X2(参数表2),.....,Xn(参数表n) { //… } 其调用顺序为先X1,X2,...,Xn(从左向右),最后为Y 析构函数的执行顺序和构造函数正好向反。 例4.11 #include <iostream.h> class X { int a; public: X(int sa) { a=sa; } //X类构造函数 int getX() { return a; } }; class Y { int b; public: Y(int sb) { b=sb; } //Y类构造函数 int getY() { return b; } };

  27. class Z:public X, private Y { int c; public: Z(int sa, int sb, int sc):X(sa),Y(sb) { c=sc; } //Z类构造函数 int getZ( ) { return c; } int getY( ) { return Y::getY( ); } }; 27 void main() { Z obj(2,4,6); int ma=obj.getX(); cout << "a=" << ma << endl; int mb=obj.getY(); cout << "b=" << mb << endl; int mc=obj.getZ(); cout << "c=" << mc << endl; }

  28. 28 base base base1 base2 derived 4.3.3 虚基类 void main( ) { derived d; d.base1::b=8; d.base2::b=15; cout << "path base1==>"<<d.base1::b<<endl; cout << "path base2==>”<<d.base2::b<<endl; } 1. 为什么要引入虚基类。 一个派生类从多个基类派生,而这些基类又有一个相同的基类,则 在派生类访问这个共同基类的成员时会产生二义性。虽然我们可以 用“作用域分辨操作符”区别,但这时基类的成员有二个副本(拷贝)。 如: class base { public: int b; }; class base1:public base { }; class base2:public base { }; class derived :public base1, public base2 { public: int fun() { } }; 程序运行结果是 path base1==>8 path base2==>15 base 类中的成员 b 有二个副本,一个放 8,一个放 15。

  29. 29 2. 虚基类的概念 void main( ) { derived d; d.base1::b=8; d.base2::b=15; cout << "path base1==>”<<d.base1::b<<endl; cout << "path base2==>”<<d.base2::b<<endl; } 如果希望基类只有一个拷贝,则在定义时把基类说明成虚基类,加上virtual: class base { public: int b; }; class base1:virtual public base { }; class base2:virtual public base { }; class derived :public base1, public base2 { public: int fun() { } }; 这时程序运行结果是 path base1==>15 path base2==>15 这时也没有了二义性,可以写成 int i=d.b;

  30. 30 例4.12 void main( ) { derived obj; } #include <iostream.h> class base{ protected: int a; public: base ( ) { a=5; } }; class base1:public base { public: base1( ) { cout <<"base1 a="<<a<<endl; } }; class base2:public base { public: base2( ) { cout <<"base2 a="<<a<<endl; } }; class deeived : public base1, public base2 { public: derived( ) { cout <<"derived a="<<a<<endl; } };

  31. 31 例4.13 void main() { derived obj; } #include <iostream.h> class base{ protected: int a; public: base() { a=5; } }; class base1:virtual public base { public: base1() { cout <<"base1 a="<<a<<endl; } }; class base2:virtual public base { public: base2() { cout <<"base2 a="<<a<<endl; } }; class deeived : public base1, public base2 { public: derived() { cout <<"derived a="<<a<<endl; } };

  32. 32 3. 虚基类的初始化 调用各类构造函数的顺序原则如下: (1) 同一层次中先调用虚基类的构造函数(不论它在何处),再是非虚基类。 (2) 若有多个虚基类在同一层次,则按它们声明的次序。 (3) 若虚基类前又由非虚基类派生而来,则仍先非虚基类,再这虚基类。 class A { .... }; class B { .... }; class C: virtual public A, virtual public B {....}; class D: virtual public B, virtual public A {....}; class E: public C, public D { ....... }; 则建立 E 的对象时: 先 C 的 A 构造函数,C 的 B ,C 再 D ( D 的 A,B是虚只一个副本 C 中已做) 最后是 E

  33. 33 例4.14 #include <iostream.h> class base { int a; public: base(int sa) //base类构造函数 { a=sa; cout<<"构造 base 类"<<endl; } }; class base1:virtual public base { int b; public: base1(int sa, int sb):base(sa) //base1类构造函数 { b=sb; cout<<"构造 base1 类"<<endl; } }; class base2:virtual public base { int c; public: base2(int sa, int sc):base(sa) //base2类构造函数 { c=sc; cout<<"构造 base2 类"<<endl; } };

  34. 34 续上 例4.14 class derived:public base1, public base2{ int d; public: derived(int sa, int sb, int sc, int sd): base(sa),base1(sa,sb),base2(sa,ac) //derived类构造函数 { d=sd; cout<<"构造 derived 类"<<endl; } }; void main() { derived obj(2,4,6,8); }

  35. 35 4.4 应用举例 例4.4.1 单继承 #include <iostream.h> class base { private: int a; public: base(int i) { a=i; cout << "构造 base" << endl; } ~base() { cout << "析放 base" <<endl; } }; class derived:public base { private: int d; public: derived(int i, int j):base(i) //derived 构造函数 { d=j; cout << "构造 derived" << endl; } ~derived() //derived 析构函数 { cout << "析放 derived" <<endl; } };

  36. 36 续上 例4.4.1 /* class derived:public base { private: int d; base member; //对象作为数据成员 public: derived(int i, int j, int k):base(i),member(j) //derived 构造函数 { d=k; cout << "构造 derived" << endl; } ~derived() //derived 析构函数 { cout << "析放 derived" <<endl; } }; */ void main( ) { derived d(5,8); }

  37. 37 例4.4.2 多层单继承 #include <iostream.h> class base1 { private: int a; public: base1(int i) { a=i; cout << "构造 base1" << endl; } ~base1() { cout << "析放 base1" <<endl; } }; class base2:public base1 { private: int b; public: base2(int i, int j):base1(j) { b=i; cout << "构造 base2" << endl; } ~base2() { cout << "析放 base2" <<endl; } };

  38. 38 续上 例4.4.2 class derived:public base2 { private: int d; public: derived(int i, int j, int k):base2(i,j) //derived 构造函数 { d=k; cout << "构造 derived" << endl; } ~derived() //derived 析构函数 { cout << "析放 derived" <<endl; } }; void main( ) { derived d(5,8,9); }

  39. 39 例4.4.3 多继承 #include <iostream.h> class base1{ public: base1() { cout << "构造 base1" <<endl; } ~base1() { cout << "析放 base1" <<endl; } }; class base2{ public: base2() { cout << "构造 base2" <<endl; } ~base2() { cout << "析放 base2" <<endl; } }; class base3{ public: base3() { cout << "构造 base3" <<endl; } ~base3() { cout << "析放 base3" <<endl; } };

  40. 40 续上 例4.4.3 class base4{ public: base4() { cout << "构造 base4" <<endl; } ~base4() { cout << "析放 base4" <<endl; } }; class derived:public base2, public base1, public base3 { private: base4 member; derived():base2(),base1(),base3() // 可缺省 { } ~derived() { } } void main( ) { derived d; }

  41. 41 例4.4.4 园circle.cpp[例4.15] #include <iostream.h> #include <graphics.h> #include <conio.h> class location{ //定义 类 Location protected: int x,y; // x,y 为保护成员 public: location(int initx, int inity) //基类Location构造函数 { x=initx; y=inity; } }; class point:public location{ //定义 类 point,为类 Location 的公有派生类 public: point(int initx, int inity):location(initx, inity) //point 类构造函数 { } void show() //用当前颜色画点 { putpixel(x,y,getcolor()); } void hide() //抹去显示点 { putpixel(x,y,getbkcolor()); }//即用背景颜色画点 void moveto(int newx, int newy) //移动显示点

  42. 42 续上_1 例4.4.4 园circle.cpp[例4.15] { hide(); //抹去原有点 x=newx; y=newy; //设置新座标位置 show(); //画新点 } }; class circles:public point{ //定义 类 circle,为类 point 的公有派生类 private: int radius; public: circles(int initx, int inity, int initradius):point(initx, inity) { radius=initradius; } //circle 类构造函数 void show() //画一个园 { circle(x,y,radius); } void hide() //抹去已显示园 { unsigned int tempcolor; tempcolor=getcolor(); //记下当前颜色 setcolor(getbkcolor()); //将背景颜色设置为当前色 circle(x,y,radius); //用此颜色画园,相当于抹去园

  43. 43 续上_2 例4.4.4 园circle.cpp[例4.15] setcolor(tempcolor); //将当前颜色恢复到原来状态 } void expand(int expandby) //放大显示的园 { hide(); //删去原有园 radius+=expandby; //增大园半径 if (radius<0) radius=0; //避免负值 show(); //画新园 } void moveto(int newx, int newy) //移动显示的园 { hide(); x=newx; y=newy; show(); } void contract(int contractby) //缩小显示的园 { expand(-contractby); } };

  44. 44 续上_3 例4.4.4 园circle.cpp[例4.15] void main() { int gdriver=DETECT, gmode; initgraph(&gdriver,&gmode,"d:\\borlandc\\bgi"); //初始化屏幕成图形模式 circles mycircle(100,200,50); //定义一个园对象 setcolor(10); //设置当前色 mycircle.show( ); //画一个园 getch( ); for(int i=0; i<=100; i++) //慢慢移动园 { for(long j=0; j<=1000000; j++); mycircle.moveto(100+i,200); } getch( );

  45. 45 int k=0; for(i=0; i<=50; i++) //慢慢放大园 { for(long j=0; j<=1000000; j++); mycircle.expand(i-k); k=i; } getch( ); k=0; for(i=0; i<=75; i++) //慢慢缩小园 { for(long j=0; j<=1000000; j++); mycircle.contract((i-k)); k=i; } getch( ); closegraph( ); //关闭图形模式 }

  46. 46 Location Location GMseeage Circle MCircle Data_rec 虚 虚 teacher student staff 例4_16在圆内显示正文 例4_17简单的大学管理系统

  47. 47 例4.4.5 单一继承实例 void main() { cbox.SetColor(5); cbox.SetWidth(3); cbox.SetHeight(50); cbox.print( ); } #include <iostream.h> class BoxShape { public: int width,height; int SetWidth(int w) { width=w; } int SetHeight(int h) { height=h; } }; class ColorBoxShape:public BoxShape { public: int color; void SetColor(int c) { color=c; } void print( ) { cout << "颜色是:"<<color<<" 宽是:"<<width<<" 高是:"<<height<<endl; } }; ColorBoxShape cbox;

  48. 48 例4.4.6 class Furniture //创建一个公共的父类 { int color, width, height; public: Furniture(int, int, int); //Furniture 构造函数声明 int GetColor() { return color; } int GetWidth() { return width; } int GetHeight() { return height; } }; Furniture::Furniture(int c, int w, int h) //Furniture 构造函数 { color=c; width=w; height=h; } //以上是Furniture类定义 class BookShelf:public Furniture //派生一个类 BookShelf { int shelves; public: BookShelf(int, int, int, int); //BookShelf 构造函数声明 int GetShelves() { return shelves; } void print() { cout<<"书架数据:"<<shelves<<endl; cout<<"颜色:"<<GetColor()<<endl; cout<<" 宽:"<<GetWidth()<<endl; cout<<" 高:"<<GetHeight()<<endl; } };

  49. 49 续上 例4.4.6 BookShelf::BookShelf(int c, int w, int h, int s):Furniture(c,w,h) { shelves=s; } //以上是BookShelf类定义 class Table:public Furniture { int drawers, material; public: Table(int, int, int, int, int); //Table 构造函数声明 int GetDrawers() { return drawers; } int GetMaterial() { return material; } void print() { cout<<"书桌数据:"<<drawers<<" "<<material<<endl; cout<<"颜色:"<<GetColor()<<endl; cout<<" 宽:"<<GetWidth()<<endl; cout<<" 高:"<<GetHeight()<<endl; } }; Table::Table(int w, int h, int c, int d, int m):Furniture(c,w,h) { drawers=d; material=m; } //以上是Table类定义 void main() { Table d(1,2,3,4,5); d.print(); BookShelf b(10,11,12,13); b.print(); }

  50. 50 例4.4.7 派生类中访问基类成员的例子 class base { //...... public: void fun(); }; class derived1:private base { public: void funder1(){ 可以访问fun() } }; class derived2:public derived1 { public: void funder2(); { 可以访问funder1(),不能访问fun() } };

More Related