一、组合(可直接访问:公有成员)
1、 组合的概念
组合,在一个类中内嵌另一个类的对象作为数据成员,该内嵌对象称为 对象成员,也称为 子对象。
class A { //.. .. };
class B { //.. .. };
class C { //.. .. };
class D {
A a;
B b;
C c;
public:
D(参数表0):a(参数表1),b(参数表2),c(参数表3)
{
// …构造函数体
}
};
2、构造顺序
构造时,子对象先构造,本对象后构造。
析构时,本对象先析构,子对象后析构。
(1)构造时,需要通过 初始化表 初始化子对象,初始化表只需紧跟构造函数的定义即可。
调用构造函数D∷D( )时,首先按各对象成员在类定义中的顺序依次调用它们的构造函数,对这些对象初始化。最后再执行D∷D( )的函数体。
(2)析构时,撤销类D的对象d1时,调用析构函数的调用顺序与调用构造函数的顺序相反。
3、访问权限
本类 可以直接访问 子对象的 公有成员,间接访问其他成员。
二、继承(可直接访问:公有成员、保护成员)
1、继承概念
类的继承就是新的类从已有类那里得到已有的特性。继承旧特性,扩展新特性。代码重用、功能扩展。
子类可以对继承的父类成员的访问属性进行更改,保护父类成员。
子类可以对继承的父类成员进行重定义,隐藏父类的成员。被隐藏的成员需用作用域标识符 :: 来访问。
子类可以对继承的父类虚函数进行重写,覆盖父类的虚函数。
2、构造顺序
构造时,基类先构造,子类再构造。
析构时,子类先析构,父类再析构。
(1)当基类的构造函数没有参数,或没有显式定义构造函数时,派生类可以不向基类传递参数,甚至可以不定义构造函数。
(2)当基类含有带参数的构造函数时,派生类必须定义构造函数,以提供把参数传递给基类构造函数的途径。
(3)当基类含有带参数的构造函数时,派生类必须定义构造函数,并缀上“:基类名(参数表) ”,以提供把参数传递给基类构造函数的途径。
(4)基类和子类对象初始化顺序
派生类名(参数总表):基类名(参数表0),对象名成员1(参数表1),…,对象成员名n (参数表n)
{
//派生类新增成员的初始化语句 ..
}
调用基类的构造函数, 对基类数据成员初始化;
调用对象成员的构造函数,对对象成员的数据成员初始化;
执行派生类的构造函数体,对派生类数据成员初始化。
class B {
int i;
public:
B(int n) {
cout << "基类构造\n";
i = n;
}
~B() {
cout << "基类析构\n";
}
void showi() {
cout << i << endl;
}
};
class D : public B {
int j;
public:
D(int a,int b):B(b), j(a) {
cout << "派生类构造\n" << endl;
//j = a;
}
~D() {
cout << "派生类析构\n" << endl;
}
void showj() {
cout << j << endl;
}
};
基类构造 ==》变量 j 初始化 ==》派生类构造 ==》派生类析构 ==》基类析构
3、访问权限,私有继承与继承私有
公有 / 保护 / 私有,继承的,基类 私有成员,在子类中不可直接访问。
公有 / 保护 / 私有,继承的,基类 公有成员、保护成员,在子类中都可以被直接访问。
(1)公有继承
class A {
private: int X;
public: int Y;
protected: int Z;
};
class B : public A{
X 不允许派生类继承,不可直接访问。
Y 在派生类中仍以公有成员的身份出现
Z 在派生类中仍以保护成员的身份出现
}
(2)保护继承
class A {
private: int X;
public: int Y;
protected: int Z;
};
class B : protected A{
X 不允许派生类继承,不可直接访问。
Y 在派生类中以保护成员的身份出现
Z 在派生类中仍以保护成员的身份出现
}
(3)私有继承
class A {
private: int X;
public: int Y;
protected: int Z;
};
class B : private A{
X 不允许派生类继承,不可直接访问。
Y 在派生类中以私有成员的身份出现
Z 在派生类中以私有成员的身份出现。
}
三、友元函数、友元类(可直接访问:公有、保护、私有成员)
1、友元函数、友元类概念
2、构造顺序
3、访问权限