类和对象的关系

类和对象

类(设计图):是对象共同特征的描述;
对象(实例):是真实客观存在的东西。
在C++中,必须先设计类,才能获得对象。

如何设计类

1
2
3
4
5
class 类名
{
//1、成员变量(代表属性,一般是名词)
//2、成员函数(代表行为,一般是动词)
};

(1)如何设计手机
属性:品牌,价格;
功能:打电话,收短信;

1
2
3
4
5
6
7
struct Phone//结构体默认的成员变量和成员函数是公开的
{
string brand;
double price;
void call(){}
void sendMessage(){}
};
1
2
3
4
5
6
7
8
class Phone//类的默认的成员变量和成员函数是私有的
{
public:
string brand;
double price;
void call(){}
void sendMessage(){}
};

创建并使用对象

类名首字母建议大写、英文、有意义,满足驼峰模式,不能用关键字,满足标识符规定;

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
34
#include <iostream>
using namespace std;
//创建
class Phone
{
public:
//属性(成员变量)
string brand;
double price;
//行为(成员函数)
void call()
{
cout << brand << "打电话" << endl;//成员函数能直接访问成员变量
return;
}
void sendMessage()
{
cout << brand << "发消息" << endl;
return;
}
};
int main()
{
//创建
Phone phone;
//赋值
phone.brand = "傻妞";
phone.price = 8848.0;

//访问函数
phone.class();
phone.sendMessage();
return 0;
}

封装

什么是封装

如何正确设计对象的属性和行为

判断依据:对象代表什么,就得封装对应的数据,并提供数据对应的行为

需求:人画圆

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
#include <iostream>
using namespace std;
struct Point
{
int x;
int y;
}
//创建
class Person
{
public:
string name;
int age;
};
class Circle
{
public:
double radius;//半径
Point center;//圆心
void draw()
{
cout << "以圆心,根据半径"<< radius <<"画圆" << endl;
return;
}
};
int main()
{

return 0;

}

private关键字

  • 是一个权限修饰符;可以修饰成员(成员变量和成员函数);
  • 被private修饰的,表示私有,只能在本类中才能使用,不能被类外代码访问;
  • 被public修饰的,表示公共的,在所有的地方都能使用;
  • 被protected修饰的,表示受保护,在本类及其派生类中访问,不能被其它类外代码直接访问。
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
34
35
#include <iostream>
using namespace std;
//创建
class Person
{
private:
int age;
public:
string name;
//set(赋值)
void setAge(int a)
{
if(a >= 0 && a<= 200)
{
age = a;
}
else
{
cout << "年龄设置不合理" << endl;
}
}
//get(获取)
int getAge const()
{
return age;
}
};
int main()
{
Person p1;
p1.name = ethaniel;
p1.setAge(100);
cout << p1.setAge << ednl;
return 0;
}

this关键字

就近原则:谁离我近(作用域),我就用谁

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Person
{
private:
int age = 20;//成员变量
public:
void method()
{
int age = 10;//局部变量
cout << age << endl;
}
};
int main()
{
Person p;
p.method();//10;
return 0;
}

this的作用:区别成员变量和局部变量

指向当前对象在成员函数内,存在指向当前对象的指针this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Person
{
private:
int age = 20;//成员变量
public:
void method()
{
int age = 10;//局部变量
cout << this->age << endl;//(*this)->age
}
};
int main()
{
Person p;
p.method();//20;
return 0;
}

构造函数

构造函数也叫作构造器、构造方法。
作用:在创建对象的时候初始化对象(对成员变量进行初始化)

构造函数格式

1
2
3
4
5
6
class 类名
{
public:
类名(){};//默认构造函数
类名(参数列表){};//带参数的构造函数
};

特点:
(1)函数名与类名相同,大小写也要一致
(2)没有返回值类型
(3)没有具体的返回值(不能由return返回结果数据)
(4)如果没有写构造函数,系统会提供默认构造函数

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
34
35
36
37
38
#include <iostream>
using namespace std;
class Student{
private:
string name;
int age;
public:
/*Student(){};*/
Student():name{},age{}{}
/*Student(string name,int age)
{
this->name = name;
this->age = age;
}*/
Student(string name,int age):name{name},age{age}{} //初始化列表
void setName(string name)
{
this->name = name;
}
string getName() const
{
return name;
}
void setAge(int age)
{
this->age = age;
}
int getAge() const
{
return age;
}
};
int main()
{ Student s1;//调用无参构造函数,初始化对象
Student s2{"ethaniel",25};//调用有参构造函数,初始化对象
cout << "s2的姓名:" << s2.getName() << " s2的年龄:" << s2.getAge() << endl;
return 0;
}

注意:
(1)构造函数的定义
1)如果没有定义构造函数,系统将给出一个默认的无参数构造函数
2)如果定义了构造函数,系统将不再提供默认的构造函数
(2)构造函数的重载
1)带参构造函数,和无参数构造函数,两者函数名相同,但是参数不同,这叫做构造函数的重载
(3)推荐的使用方式
1)无论是否使用,都手动书写无参数构造函数,和带全部参数的构造函数

析构函数

作用:用于在对象被销毁时进行清理操作;
格式:与类名相同,前面加上波浪号(~),没有返回类型,并且不带参数。

1
2
3
4
5
6
7
8
class 类名
{
public:
~类名()
{
cout << "系统函数,删除对象" <<endl;
};
};

对象在离开作用域时,会被销毁,从而系统自动调用合适的析构函数

例题:
定义一个汽车类Car,包含一个引擎对象Engine,以及速度状态值汽车对象具有启动、加速、减速和停止等操作,均委托给引擎对象来完成

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include <iostream>
using namespace std;
class Engine
{
public:
void start()
{
cout << "引擎启动" <<endl;
}
void stop()
{
cout << "引擎熄火" <<endl;
}
void speedUp()
{
cout << "引擎提速" <<endl;
}
void speedDone()
{
cout << "引擎减速" <<endl;
}
};
class Car
{
private:
Engine engine;
int speed;
public:
Car():engine{},speed{}{}
Car(Engine engine,int speed):engine{engine},speed{speed}{}
void setEngine(Engine engine)
{
this->engine = engine;
}
Engine getEngine()const
{
return engine;
}
void setSpeed(int speed)
{
this->speed = speed;
}
int getSpeed()const
{
return speed;
}
void start()
{
engine.start();
speed += 10;
}
void stop()
{
engine.stop();
speed = 0;
}
void speedUp()
{
engine.speedUp();
speed += 10;
if(speed > 100)
{
speed = 100;
}
}
void speedDone()
{
engine.speedDone();
speed -= 10;
if(speed < 0)
{
speed = 0;
}
}
void showCarStatus()
{
cout << "汽车当前速度是:" << speed << endl;
if (speed > 0)
{
cout << "汽车在行驶中" << endl;
}
else
{
cout << "汽车停止状态" << endl;
}
}
};
int main()
{
Engine eng;
Car car{eng,0};
car.start();
car.showCarStatus();
car.speedUp();
car.speedUp();
car.showCarStatus();
car.speedDone();
car.showCarStatus();
car.stop();
car.showCarStatus();
return 0;
}