c++之继承一
has-A,uses-A 和 is-A
has-A : 包含关系,用以描述一个类由多个“部件类”构成。实现has-A关系用类成员表示,即一个类中的数据成员是另一种已经定义的类。
uses-A : 一个类部分地使用另一个类。通过类之间成员函数的相互联系,定义友元或对象参数传递实现。
is-A : 机制称为“继承”。关系具有传递性,不具有对称性。
继承 是类之间定义的一种重要关系
一个 B 类继承A类,或称从类 A 派生类 B
类 A 称为基类(父类),类 B 称为派生类(子类)
c++支持多继承
类继承关系的语法形式
class 派生类名 : 基类名表
{
数据成员和成员函数声明
};
派生类对基类成员的使用,与继承访问控制和基类中成员性质有关
public:公有继承 基类的公有成员-》派生类的公有成员
基类的保护成员-》派生类的保护成员
private:私有继承 基类的公有成员和保护成员-》派生类的私有成员
protected:保护继承 基类的公有成员和保护成员-》派生类的保护成员
不论哪种方式继承基类,派生类都不能直接使用基类的私有成员
1.共有继承::
1 #include <iostream> 2 using namespace std; 3 4 class A 5 { 6 public: 7 void get_XY() 8 { 9 cout << "Enter two numbers of x,y:"<< endl; 10 cin>>x>>y; 11 } 12 void output_XY() 13 { 14 cout << "x=" << x << '\t' << "y=" << y << endl; 15 } 16 protected: //保护数据成员,在类层次中可见 17 int x,y; 18 }; 19 class B: public A 20 { 21 public: 22 int get_S() 23 { 24 return s; 25 } 26 void make_S() 27 { 28 s = x*y; 29 } 30 protected: 31 int s; 32 }; 33 class C:public B 34 { 35 public: 36 void getH() 37 { 38 cout <<"Enter a number h:"; 39 cin>>h; 40 } 41 int getV() 42 { 43 return v; 44 } 45 void makeV() 46 { 47 make_S(); 48 v = get_S() * h; 49 } 50 protected: 51 int h,v; 52 }; 53 int main() 54 { A objA ; 55 B objB ; 56 C objC ; 57 cout << "It is object_A :\n" ; 58 objA.get_XY() ; 59 objA.output_XY() ; 60 cout << "It is object_B :\n" ; 61 objB.get_XY() ; 62 objB.make_S() ; 63 cout << "S = " << objB.get_S() << endl ; 64 cout << "It is object_C :\n" ; 65 objC.get_XY() ; 66 objC.getH(); 67 objC.makeV() ; 68 cout << "V = " << objC.getV() << endl ; 69 }
2.私有继承:
1 #include<iostream> 2 using namespace std ; 3 class A 4 { public : 5 void get_XY() 6 { 7 cout << "Enter two numbers of x and y : " ; 8 cin >> x >> y ; 9 } 10 void put_XY() 11 { 12 cout << "x = "<< x << ", y = " << y << '\n' ; 13 } 14 protected: 15 int x, y ; 16 }; 17 class B : private A 18 { public : 19 int get_S() 20 { 21 return s ; 22 } 23 void make_S() 24 { 25 get_XY(); 26 s = x * y ; 27 } 28 private: 29 int s ; 30 }; 31 int main() 32 { B objB ; 33 cout << "It is object_B :\n" ; 34 objB.make_S() ; 35 cout << "S = " << objB.get_S() << endl ; 36 }
3。重名成员
派生类定义了与基类同名的成员,在派生类中访问同名成员
时屏蔽了基类的同名成员
在派生类中使用基类的同名成员,显式地使用类名限定符:
类名 :: 成员
基类成员的作用域延伸到所有派生类
4,在派生类中访问静态成员
基类定义的静态成员,将被所有派生类共享
根据静态成员自身的访问特性和派生类的继承方式,在类层次
体系中具有不同的访问性质
派生类中访问静态成员,用以下形式显式说明:
类名 :: 成员
或通过对象访问 对象名 . 成员
1 #include <iostream> 2 using namespace std; 3 4 class A 5 { 6 public: 7 //静态成员变量 8 static int i; 9 //静态成员函数 10 static void add() 11 { 12 i++; 13 } 14 void output() 15 { 16 cout << "static i = " << i << endl; 17 }; 18 }; 19 //必须进行初始化,否则会报错 20 int A::i = 0; 21 class B: private A 22 { 23 public: 24 void f() 25 { 26 i = 5; 27 add(); 28 B::i++; 29 B::add(); 30 } 31 }; 32 void main() 33 { 34 //不管是怎么调用i,操作的都是同一个数据 35 B b; 36 A a; 37 a.add(); 38 a.output(); 39 b.f(); 40 //访问A类的静态数据成员 41 cout << "static i=" << A::i << endl; 42 //通过A类的对象访问静态数据成员 43 cout << "static i=" << a.i << endl; 44 //下面的代码会报错,因为i是类B的私有静态数据成员,不能直接访问 45 //cout << "static i=" << b.i << endl; 46 }
1 #include <iostream> 2 using namespace std; 3 4 class A 5 { 6 public: 7 //静态成员变量 8 static int i; 9 //静态成员函数 10 static void add() 11 { 12 i++; 13 } 14 void output() 15 { 16 cout << "static i = " << i << endl; 17 }; 18 }; 19 //必须进行初始化,否则会报错 20 int A::i = 0; 21 class B: private A 22 { 23 public: 24 void f() 25 { 26 i = 5; 27 add(); 28 B::i++; 29 B::add(); 30 } 31 }; 32 void main() 33 { 34 //不管是怎么调用i,操作的都是同一个数据 35 B b; 36 A a; 37 a.add(); 38 a.output(); 39 b.f(); 40 //访问A类的静态数据成员 41 cout << "static i=" << A::i << endl; 42 //通过A类的对象访问静态数据成员 43 cout << "static i=" << a.i << endl; 44 //下面的代码会报错,因为i是类B的私有静态数据成员,不能直接访问 45 //cout << "static i=" << b.i << endl; 46 }
5,基类的初始化
建立一个类层次后,通常创建某个派生类的对象,包括使用基类的数据和函数。
C++提供一种机制,在创建派生类对象时用指定参数调用基类的构造函数来初始化派生类继承基类的数据
派生类构造函数声明为
派生类构造函数 ( 变元表 ) : 基类 ( 变元表 ) , 对象成员1( 变元表 )
… 对象成员n ( 变元表 ) ;
构造函数执行顺序:基类 à 对象成员à 派生类。
1 #include <iostream> 2 using namespace std; 3 4 class ParentClass 5 { 6 private: 7 int date1,date2; 8 public: 9 ParentClass(int d1,int d2) 10 { 11 date1 = d1; 12 date2 = d2; 13 } 14 int increase1() 15 { 16 return ++date1; 17 } 18 int increase2() 19 { 20 return ++date2; 21 } 22 void display() 23 { 24 cout << "date1 = " << date1 << ";" << "date2 = " << date2 << endl; 25 } 26 }; 27 class DerivedClass:private ParentClass 28 { 29 private: 30 int date3; 31 ParentClass date4; 32 public: 33 //使用初始化式,调用基类构造函数初始化成员变量和构造对象成员 34 DerivedClass(int d1,int d2,int d3,int d4,int d5):ParentClass(d1,d2),date4(d4,d5) 35 { 36 date3 = d3; 37 } 38 int increase1() 39 { 40 return ParentClass::increase1(); 41 } 42 int increase3() 43 { 44 return ++date3; 45 } 46 void display() 47 { 48 ParentClass::display(); 49 cout << "date3 = " << date3 << endl; 50 date4.display(); 51 } 52 }; 53 void main() 54 { 55 DerivedClass d1(17,18,1,2,-5); 56 d1.increase1(); 57 d1.display(); 58 }
奋斗和第三方