一:基础知识
1.基类与派生类
(1)继承语法形式:
class 派生类名:基类名表
{
数据成员和成员函数声明
};
基类类名表构成:
访问控制 基类名
访问控制有三种{public:公有继承
private:私有继承
protected:保护继承
}
无论哪种类型都不能直接访问基类私有成员。
2.派生类生成的过程
(1)吸收基类成员(构造和析构函数除外,不一定可见)
(2)改造基类成员(根据派生类成员函数,覆盖基类)
(3)添加派生类新成员
-
#include <iostream>
-
using namespace std ;
-
class A
-
{ public :
-
void get_XY()
-
{ cout << "Enter two numbers of x, y : " ; cin >> x >> y ; }
-
void put_XY() { cout << "x = "<< x << ", y = " << y << '\n' ; }
-
protected: int x, y;
-
};
-
class B : public A
-
{ public :
-
int get_S() { return s ; };
-
void make_S() { s = x * y ; };
-
protected: int s;
-
};
-
class C : public B
-
{ public :
-
void get_H() { cout << " Enter a number of h : " ; cin >> h ; }
-
int get_V() { return v ; }
-
void make_V() { make_S(); v = get_S() * h ; }
-
protected: int h, v;
-
};
-
int main()
-
{ A objA ;
-
B objB ;
-
C objC ;
-
cout << "It is object_A :\n" ;
-
objA.get_XY() ;
-
objA.put_XY() ;
-
cout << " It is object_B :\ n" ;
-
objB.get_XY() ;
-
objB.make_S() ;
-
cout << " S = " << objB.get_S() << endl ;
-
cout << " It is object_C :\ n" ;
-
objC.get_XY() ;
-
objC.get_H();
-
objC.make_V() ;
-
cout << " V = " << objC.get_V() << endl ;
-
}
-
3.重名成员
派生类中定义与基类同名成员,屏蔽基类成员,如在派生类中使用基类同名成员,显式地使用类名限定符
形式 类名:成员
4.基类初始化
在创建派生类对象时,用指定参数调用基类的构造函数,初始化派生类继承基类的数据。
形式 派生类构造函数 ( 变元表 ) : 基类 ( 变元表 ) , 对象成员1( 变元表 ).........;
构造函数顺序:基类 对象成员 派生类
基类可以定义一个无参的构造函数。
注:
派生类构造函数析构函数使用原则:
(1)基类的构造函数和析构函数不能被继承
(2)如果基类没有定义构造函数或有无参的构造函数, 派生类也可以不用定义构造函数
(3)如果基类没有无参的构造函数,派生类必须定义构造函数
(4)如果派生类的基类也是派生类,则每个派生类只负责最近的基类的构造
(5)派生类是否定义析构函数与所属的基类无关
派生类析构函数执行顺序问题
(1)当派生类中不含对象成员时
构造函数的执行顺序是 基类 派生类;
析构函数的执行顺序是 派生类→基类。
(2)当派生类中含有对象成员时
构造函数的执行顺序 基类→对象成员→派生类;-
-
using namespace std ;
-
class parent_class
-
{ int data1 , data2 ;
-
public :
-
parent_class ( int p1 , int p2 ) { data1 = p1;
-
data2 = p2; }
-
int inc1 () { return ++ data1; }
-
int inc2 () { return ++ data2 ; }
-
void display () { cout << "data1=" << data1 << " , data2=" << data2 << endl ; }
-
};
-
class derived_class : private parent_class
-
{ int data3 ;
-
parent_class data4 ;
-
public:
-
derived_class ( int p1 , int p2 , int p3 , int p4 , int p5 ): parent_class ( p1 , p2 ) , data4 ( p3 , p4 )
-
{ data3 = p5 ; }
-
int inc1 ( ) { return parent_class :: inc1 ( ) ; }
-
int inc3 ( ) { return ++ data3 ; }
-
void display ( )
-
{ parent_class :: display ( ) ; data4.display ( ) ;
-
cout << "data3=" << data3 << endl ;
-
}
-
} ;
-
int main ( )
-
{ derived_class d1 ( 17 , 18 , 1 , 2 , -5 ) ;
-
d1 . inc1 ( ) ;
-
d1 . display ( ) ; }
(3)吸收基类成员:除构造和析构函数外
改造基类成员:通过在派生类中定义同名成员屏蔽在派生类中不起作用的部分基类成员。
添加新成员
5.多继承
一个类有多个直接基类的继承关系称为多继承
多继承声明语法
class 派生类名: 访问控制 基类名1 , 访问控制 基类名2 , … , 访问控制 基类名n
{
数据成员和成员函数声明
};
不建议使用,了解即可
6.赋值兼容原则
指程序中需要使用基类的地方可以用公有派生类的对象代替。
赋值兼容规则中所指的替代包括以下的情况:
1).派生类的对象可以赋给基类对象
例:
Base b;
Derived d;
b=d;
b中所有数据成员都具有对象d中对应数据成员的值
2).派生类的对象可以初始化基类的引用
3).派生类的对象的地址可以赋给基类类型的指针
其中最常用的是第三条,在使用虚函数多态时使用,被赋值的基类指针,只能访问派生类中从基类继承来的成员,而不能访问派生类独有的成员。且公有继承下主函数中的对象成员或基类指针只能访问相应类的公有类型数据成员或函数。
只能派生类赋值给基类,基类无法赋值给派生类,道理很简单,因为派生类数据比基类多。
二:心得体会
继承就是从一个已有类中继承数据成员。当有多个类有着相同的数据成员时,可以用继承,缩短代码长度。继承的使用可以简便程序,可以减少代码的重复书写,在以后的学习中肯定会写越来越多的代码,实现更多功能,代码就可能会比较长和复杂,使用继承代码就会精简许多,更方便调用和对错误的修改。