1.构造函数
- 一般而言,是公有权限,否则无法创建对象
- 无返回值,名称与类类名一致
- 每个类必有,如果没写那么系统会自动产生一个无参的空版本
- 跟普通函数一样可以重载,可以有默认参数等等
- 每当定义一个对象,对应版本的构造函数会被自动调用
- 主要功能就是初始化类成员
2.析构函数
- 一般而言,是公有权限,否则无法正确释放对象资源
- 无返回值,名称前有~且名称与类名一致
- 每个类必有,如果没写那么系统会自动产生一个空版本
- 不可重载,析构函数的接口是固定的
- 每当一个对象被释放,对应的析构函数会被自动调用
- 主要功能就是释放类内部额外申请的资源(尤其是内存)
3.私有成员
- 逻辑上,符合类的一个初衷:数据隐藏。内部数据封装为私有才能保证安全性,也简化了使用接口
- 语法上:私有成员只能被本类的方法访问,即只能在本类域内访问
student xx("a",100);
xx.私有成员 //这是错误的
4.静态成员
- 逻辑上,凡是属于整个类(而不是某个对象)的对象和方法都应该设计为静态成员(比如班级的平均分,不属于某个学生对象,而是属于真个类)
- 语法上:静态成员在类外分配内存,与具体对象的内存管理是分开的,独立的
- 静态成员,
必须
在类外部定义 - 在类中static int xxx; 语句只是
声明
,使得类域外部的数据被囊括在本类内部
5.类对象成员
- 顾名思义,首先是一个成员,成员的类型是类对象。
- 类对象成员必须放在初始化列表来初始化化
- 类对象成员初始化顺序跟定义时为准,不与初始化列表相关
//has a 关系
class Line
{
// 包含两个点
// 类对象成员
Point p1;
Point p2;
public:
Line(Point p1, Point p2);
// 获取线段长度
float length();
};
6、has-a关系、对象初始化列表
- 对象初始化列表的两种方法
- has-a 关系一般对应类对象成员,不是类的继承
Line::Line(Point p1, Point p2)
:p1(p1), p2(p2) // 类成员对象的初始化
{
}
Line::Line(float x1, float y1, float x2, float y2)
:p1(x1, y1), p2(x2, y2) // 类成员对象的初始化
7、对象包含关系中构造函数、析构函数执行次序
- 构造整体先是构造部分,再构造整体
- 析构整体先是析构整体,再析构部分
class Part1
{
public:
Part1(){cout << "P1" << endl;}
~Part1(){cout << "~P1" << endl;}
};
class Part2
{
public:
Part2(){cout << "P2" << endl;}
~Part2(){cout << "~P2" << endl;}
};
class Whole
{
Part1 p1;
Part2 p2;
public:
Whole(){cout << "W" << endl;}
~Whole(){cout << "~W" << endl;}
};
int main(int argc, char **argv)
{
Whole w;
return 0;
}
执行效果:
gec@ubuntu:~$ ./main
P1
P2
W
~W
~P2
~P1