第六章 继承性和派生类 胡昊 南京大学计算机系软件所
重要内容
继承例子 图形 闭合图形 开放图形 多边形 椭圆形 椭圆形 椭圆形 椭圆形 多边形 多边形 多边形
基 类 public: protected: private: general users derived class’s member functions and friends own member functions and friends 基 类 public: protected: private:
继承方式:public方式 基类的对象a 可访问性: a.f(): OK; a.g(): Error; a.h(): Error; 基类A 成员: f(): public; g(): protected; h(): private; 派生类B 成员: f(): public; g(): protected; h(): NONO; 派生类的对象b 可访问性: b.f(): OK; b.g(): Error; b.h(): Error; 派生类的派生类的对象c 派生类的派生类C 可访问性: f(): OK; g(): OK; h(): Error; 可访问性: f(): OK; g(): OK; h(): Error;
继承方式:protected方式 基类的对象a 可访问性: a.f(): OK; a.g(): Error; a.h(): Error; 成员: f(): public; g(): protected; h(): private; 派生类B 成员: f(): protected; g(): protected; h(): NONO; 派生类的对象b 可访问性: b.f(): Error; b.g(): Error; b.h(): Error; 派生类的派生类C 派生类的派生类的对象c 可访问性: f(): OK; g(): OK; h(): Error; 可访问性: f(): OK; g(): OK; h(): Error;
继承方式:private方式 基类的对象a 可访问性: a.f(): OK; a.g(): Error; a.h(): Error; 基类A 成员: f(): public; g(): protected; h(): private; 派生类B 成员: f(): private; g(): private; h(): NONO; 派生类的对象b 可访问性: b.f(): Error; b.g(): Error; b.h(): Error; 派生类的派生类C 派生类的派生类的对象c 可访问性: f(): OK; g(): OK; h(): Error; 可访问性: f(): Error; g(): Error; h(): Error;
class A { public: void f(); protected: void g(); private: void h(); }; class B: protected A //g对A类成员的访问不受B的继承方式影响,除了h,其他都能访问 class C: public B { public: void r() q(); //OK f(); //OK g(); //OK h(); //Error } }; B b; b.q(); //OK b.f(); //Error b.g(); //Error b.h(); //Error
class A { public: void f1(); void f2(); void f3(); protected: class B: private A { public: A::f1; A::g1; protected: A::f2; A::g2; private: A::f3; }; B b; b.f1(); b.g1(); b.f2(); b.g2(); class A { public: void f1(); void f2(); void f3(); protected: void g1(); void g2(); void g3(); }; // ok // error
class A { int x, y; public: void f(); void g() { ... x ... } }; class B: public A { int z; void h() { ... x ... g(); } // error // ok
派生类对象的初始化和赋值操作 B b1; class A B b2(1); { B b3(1, 2); int x; public: A() {x=0;} A(int i) {x=i; } }; class B: public A int y; B() {y=0;} B(int i) {y=i;} B(int i, int j):A(i) {y=j; }
单继承举例Employee (一) class Employee //普通职员类 { String name; int salary; public: Employee(const char *s, int n=0): name(s) salary = n; } void set_salary(int n) { salary = n; } int get_salary() const { return salary; } String get_name() const { return name; } };
单继承举例Employee (二) const int MAX_NUM_OF_EMPS=20; class Manager: public Employee //部门经理 { Employee *group[MAX_NUM_OF_EMPS]; int num_of_emps; public: Manager(const char *s, int n=0): Employee(s,n) num_of_emps = 0; } Employee *add_employee(Employee *e) if (num_of_emps >= MAX_NUM_OF_EMPS) return NULL; group[num_of_emps] = e; num_of_emps++; return e;
单继承举例Employee (三) Employee *remove_employee(Employee *e) { int i; for (i=0; i<num_of_emps; i++) if (e->get_name() = = group[i]->get_name()) break; if (i < num_of_emps) int j; for(j=i+1; j<num_of_emps; j++) group[j-1] = group[j]; num_of_emps--; return e; } else return NULL; };
单继承举例LinearList (一) class LinearList { ...... public: { ...... public: bool insert( int x, int pos ); bool remove( int &x, int pos ); int element( int pos ) const; int search( int x ) const; int length( ) const; };
单继承举例LinearList(二) class Queue: private LinearList { public: bool en_queue(int x) { return insert(x,length()); } bool de_queue(int &x) return remove(x,1); };
名冲突(1) class A { public: void f(); void g(); }; class B { void h(); class C: public A, public B void func() {f(); } //error, 是A的f,还是B的f } C c; c.f(); //error, 是A的f, 还是B的f
名冲突(2) class C: public A, public B { public: void func() A::f(); //OK, 调用A的f。 B::f(); //OK, 调用B的f。 } }; C c; c.A::f(); //OK, 调用A的f c.B::f(); //OK, 调用B的f
重复继承(1) class X{ public: int a; void X(){ a=10; } }; class X1:public x{ x1(){ cout<< a<<endl; } } class X2:public x{ X2(){ cout<< a<<endl;
重复继承(2) X X2 X1 Y class Y : public X1,public X2{ public: Y(){ cout<< a << endl; } }; void f(Y* pY ){ pY->a = 0; //error pY->X::a = 0; //error pY->X1::a = 0; pY->X2::a = 0; X1 X X2 Y
重复继承-虚基类(3) class X { public: int a; void X(){ a=10; } }; class X1: virtual public X { } class X2: virtual public X class Y: public X1, public X2
虚基类的派生类对象存储结构示意图: X X1 X2 Y b1 b2 d X1类子对象 X2类子对象 Y类对象 a X类子对象