一、派生类访问静态成员
1、基类定义的静态成员,将被所有派生类共享(基类和派生类共享基类中的静态成员)
2、根据静态成员自身的访问特性和派生类的继承方式,在类层次体系中具有不同的访问性质
3、派生类中访问静态成员结构:
类名 :: 成员
或通过对象访问 对象名 . 成员
二、基类的初始化
1、在创建派生类对象时用指定参数调用基类的构造函数来初始化派生类继承基类的数据
2、派生类构造函数结构:
派生类构造函数( 变元表) : 基类 ( 变元表 ) , 对象成员1( 变元表)
… 对象成员n ( 变元表 ) ;
3、构造函数执行顺序:基类 à 对象成员à 派生类
4、举例
调用构造函数顺序测试,构造函数无参数
#include<iostream>
using namespace std ;
class Base
{ public : Base ( ) { cout<< "Base created.\n" ; }
} ;
class D_class : public Base
{ public : D_class ( ) { cout<< "D_class created.\n" ; }
} ;
int main ( )
{ D_class d1 ; }
#include<iostream>
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 ( ) ; }
三、派生类构造函数和析构函数的定义规则
派生类构造函数和析构函数的使用原则
- 基类的构造函数和析构函数不能被继承
- 如果基类没有定义构造函数或有无参的构造函数, 派生类也可以不用定义构造函数
- 如果基类无无参的构造函数,派生类必须定义构造函数
- 如果派生类的基类也是派生类,则每个派生类只负责直接基类的构造
- 派生类是否定义析构函数与所属的基类无关
6、结构
派生类::派生类名(参数总表):基类名(参数表)
{
// 派生类新增成员的初始化语句
}
ps:这是基类有构造函数且含有参数时使用
四、派生类析构函数
(1)当派生类中不含对象成员时
1、在创建派生类对象时,构造函数的执行顺序是:基类的构造函数→派生类的构造函数;
2、在撤消派生类对象时,析构函数的执行顺序是:派生类的析构函数→基类的析构函数。
(2)当派生类中含有对象成员时
1、在定义派生类对象时,构造函数的执行顺序:基类的构造函数→对象成员的构造函数→派生类的构造函数;
2、在撤消派生类对象时,析构函数的执行顺序:派生类的析构函数→对象成员的析构函数→基类的析构函数。
(3)举例
#include<iostream.h>
class base {
intn;
public:
base(inta) {
cout<<"constructingbase class"<<endl;
n=a; cout<<"n="<<n<<endl; }
~base(){cout<<"destructingbase class"<<endl;}
};
class subs:public base {
basebobj; int m;
public:
subs(inta,int b,int c):base(a),bobj(c) {
cout<<"constructingsub cass"<<endl;
m=b; cout<<"m="<<m<<endl; }
~subs(){cout<<"destructingsub class"<<endl;}
};
void main() {
subss(1,2,3); }
五、多继承的派生类构造和访问
1、多个基类的派生类构造函数可以用初始式调用基类构造函数初始化数据成员。
2、执行顺序与单继承构造函数情况类似。多个直接基类构造函数执行顺序取决于定义派生类时指定的各个继承基类的顺序。
3、 一个派生类对象拥有多个直接或间接基类的成员。不同名成员访问不会出现二义性。如果不同的基类有同名成员,派生类对象访问时应该加以识别。
4、结构
派生类名(参数总表):基类名1(参数表1),基类名2(参数表2),…,基类名n(参数表n)
{
// 派生类新增成员的初始化语句
}
5、举例
class Base1
{ public:
Base1(int x) { value = x ; }
int getData() const { return value ; }
protected:
int value;
};
class Base2
{ public:
Base2(char c) { letter=c; }
char getData() const { return letter;}
protected:
char letter;
};
class Derived : public Base1, publicBase2
{ friend ostream &operator<< ( ostream &, const Derived& ) ;
public :
Derived ( int, char, double ) ;
double getReal() const ;
private :
double real ;
};
六、多继承方式下构造函数的执行顺序
1、先执行所有基类的构造函数,再执行对象成员的构造函数,最后执行派生类的构造函数
2、处于同一层次的各基类构造函数的执行顺序取决于定义派生类时所指定的基类顺序
与派生类构造函数中所定义的成员初始化列表顺序没有关系。
3、内嵌对象成员的构造函数执行顺序与对象在派生类中声明的顺序一致