1. 面向对象

1.1 对象和类

  • 对象:描述其属性的数据以及对这些数据施加的一组操作封装在一起构成的统一体。对象可认为是数据+操作。

  • :类是具有相同的数据和相同的操作的一组对象的集合。

  • 对象和类:类和对象之间是抽象与具体的关系。类是一个模板是对一类事物的抽象描述,而对象用于表示现实中该事物的个体。类是在对象之上的抽象,对象则是类的具体化,是类的实例。

  • 消息传递:对象之间的交互。

  • 方法:对象实现的行为称为方法。

  • 面向对象程序设计的基本特征:抽象、封装、继承、多态。

1.2 对象的定义、声明、初始化

  • 定义:将一段计算机内存和变量名关联起来。对于一个对象,定义只能进行一次。

  • 声明:变量声明是一个语句,指定变量名称和类型,它只是说明系统内有这样一个变量(只要有声明存在,compiling时不会报错,link时ing可能报错),定义可以在其他地方完成。一个对象可以多次声明。

  • 初始化:将初始值赋给变量的声明称为初始化,一般有三种方式:

1
2
3
int m1 = 10;        //变量赋值
int m2 (10); //函数赋值(像构造函数),与楼上等价
int m3 {3}; //初始化列表(有时也代表结构体)

1.3 动态内存分配

  • new:为对象申请内存空间,返回值是该类型的指针。
1
2
3
4
new int            // 与 malloc(sizeof(int)) 可以视为等价
new stash(类名) // 申请空间后完成对象初始化(调用构造函数)
new int[10] // 申请多个连续空间
new stash[10] // 连续新建10个对象并初始化
  • delete:收回对象内存空间。
1
2
delete p;         // 收回空间
delete[] p; // 收回多个控件(方括号中不能写数量)
  • new/delete 是运算符,malloc/free是函数,new会调用构造函数(分配空间+初始化),molloc不会(只分配空间),delete会调用析构函数。

  • 在同一程序中,不允许同时使用 {new,delete} 和 {malloc,free},两套机制会竞争内存空间。

1.4 引用

1
2
3
char c;            // a character
char *p = &c; // a pointer to a character
char &r = c; // a reference to character
  • 引用类型变量和代表的变量的绑定(别名)
  • 一旦进行引用,就是不能改变的,但可以有多个别名
  • 对于全局变量/本地变量,在引用声明时必须同时进行绑定
  • 对于结构体内/参数列表,不需要给出绑定
  • 没有引用的数组,但有数组的引用
  • 引用无法绑定引用
1
2
3
int x = 47;
int& y = x; // reference
cout << "x=" << x;

输出结果为“x=47”。

1.5 面向对象

  • 形参的const:告诉调用者保证不改变实参

例:二维点的移动

C:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
using namespace std;

typedef struct
{
float x;
float y;
} Point;

void print(const Point *p)
{
cout << p->x << "," << p->y << endl;
}

void move(Point *p, int dx, int dy)
{
p->x += dx;
p->y += dy;
}

int main()
{
Point a,b;
a.x = b.x = a.y = b.y = 0;
move(&a,2,2);
print(&a);
print(&b);
}

Cpp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
using namespace std;

struct Point
{
float x;
float y;
void print() // 可以在struct内定义
{
cout << x << "," << y << endl; // 不需要指针访问
}
void move(float dx, float dy); // 可以在struct内声明
void init(int ix, int iy)
{
x=ix; y=iy; // 新的初始化方式
}
} ;

void Point::move(float dx, float dy)
{
x += dx; // 不需要指针访问
y += dy;
}

int main()
{
Point a,b;
a.init(0,0);
b.init(0,0);
a.move(2,2); // 成员引用式调用函数
a.print();
b.print();
}
  • 可以将函数定义或函数声明放置在struct内
  • 对象指定无需传参,只需要用结构体方式调用函数
  • 常常包含初始化函数
  • "::"标点符号用于连接类名和函数名
  • 成员函数内隐藏的this指针指向对象(对于本例,有隐藏Point *this)
    • cout << this; 输出对象地址
    • x 也可也写作 this->x

1.6 构造函数和析构函数

  • struct能够直接访问里面的所有东西,class默认全部不能访问,从"public:"起能够访问,从"private:"起为无法访问的

  • 建立与类同名的函数作为构造函数,其意义是在新建对象的同时进行赋值

  • 拥有构造函数的类不再支持struct大括号赋值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class Point
{
private:
float x;
float y;
public:
void print();
void move(float dx, float dy);
Point(int ix, int iy); // 构造函数
Point(int iz); // cpp支持同名函数
} ;

void Point::print()
{
cout << x << "," << y << endl;
}

void Point::move(float dx, float dy)
{
x += dx;
y += dy;
}

Point::Point(int ix, int iy)
{
x=ix; y=iy;
}

Point::Point(int iz)
{
x=y=iz;
}
  • 析构函数的命名为"~"+对象名

  • 析构的顺序为构造的逆序

  • 在程序结束时,所有对象自动调用析构函数

1
2
3
4
~Point()
{
cout << "~" << x << "," << y ;
}

最后输出结果为"~4,4~3,5"