第二章 从结构到类的演变
**大家想一起学习交流的可以加群,QQ:755422568。**
一、结构的演化
(1)、结构发生质的演变
1)、函数与数据共存
C++允许结构中可以定义函数,这些函数称为成员函数。原来的结构成员称之数据成员。
struct 结构名 {
数据成员
成员函数
}
2)、封装性
没有使用private定义的成员,默认为public。
如果在定义结构时,将数据成员使用private关键字定义,则产生了封装性。
私有的数据成员只有通过公有的成员函数才能使用,这就称为数据的封装性
private: int a; //私有的数据成员
3)、使用构造函数初始化结构的对象
#include <iostream>
using namespace std;
struct Points{
private:
double x,y; //数据成员
public:
Points(){}; //无参的构造函数
Points(double a,double b){ //两个有参的构造函数
x = a;
y = b;
};
void Setxy(double a,double b){ //成员函数,用来设置数据成员
x = a;
y = b;
}
void Display(){ //成员函数,用来按指定格式输出数据成员的值
cout << "成员的值:" << x << "\t" << y << endl;
}
};
void main(){
Points a; //定义对象a
Points b(18.5,10.6); //定义对象b并赋初始值,使用该方法赋初始值。
a.Setxy(10.6,18.5); //设置对象a的数据成员
cout << "显示p的数据成员:" << endl;
a.Display(); //显示a的数据成员
cout << "显示p2的数据成员:" << endl;
b.Display(); //显示b的数据成员
/**
* 显示p的数据成员:
* 成员的值:10.6 18.5
* 显示p2的数据成员:
* 成员的值:18.5 10.6
*/
}
二、从结构演变一个简单的类
使用关键字class代替struct,这就是一个标准的类。
例子:
class Points{...}
三、面向过程与面向对象
1)、所谓“面向过程”
,就是不必了解计算机的内部逻辑,在把精力主要集中在对如何求解问题的算法逻辑和过程的描述上,通过编写程序把解决问题的步骤告诉计算机。
2)、所谓函数,就是模块的基本单位,是对处理问题的一种抽象,把一切逻辑功能完全独立的或相对独立的程序部分都设计成函数,并让每一个函数只完成一个功能。这样,一个函数就是一个程序模块,程序的各个部分除了必要的信息交流之外,互不影响。相互隔离的程序设计方法就是模块化程序设计方法。
3)、面向过程会存在以下问题:
1、要求开发人员按照计算机的结构思考,而不是按要解决问题的结构去思考。
2、开发员必须在机器模型(解空间)和实际问题模型(问题空间)之间进行对应。
4)、相对于过程,对象是稳定的,将现实世界中客观存在的事物称之为对象,实际上是功能抽象和数据抽象的统一。
5)、结构化程序设计使用的是功能抽象,以函数过程和数据结构为中心。
在面向对象程序设计中,不仅可以进行功能抽象,而且能进行数据抽象,以对象代表问题为中心。
6)、软件开发者将被开发的整个业务范围称作“问题域”。
7)、描述:指用一种语言把人们对问题域中事物的认识,对问题及其解决方法的认识描述出来。
四、面向对象的设计特点
(选择、填空、简答)
1)、对象
通过抽象归纳,可以使用 对象名、属性和操作
三要素来描述对象。对象名用来标识一个具体的对象,用数据来表示对象的属性,用操作来描述对象的动态特征(使用函数实现操作,也称为方法)。数据称为数据成员,函数称为成员函数。
2)、抽象和类
抽象是一种从一般观点看待事物的方法,即集中于事物的本质特征,而不是具体细节或具体实现。类模型由类名、一组属性、一组操作3部分组成,类的属性只是性质的说明,对象的属性才是具体的数据。类是一组具有相同的属性和操作的一组对象的集合,类的作用是用来定义对象,而对象是类的一个实例
。
3)、封装
一个对象的属性和操作是紧密结合的,对象的属性只能由这个对象的操作来存取,对象的操作分为内部操作和外部操作。内部操作只供对象内部的其他操作使用,不对外提供。外部操作对外提供一个消息接口,通过这个接口接收对象外部的消息并为之提供操作服务。简单来说,封装就是把对象的属性和操作结合成一个独立的系统单位,并尽可能的隐藏对象的内部细节。
在类中,封装是通过存取权限来实现的,对象的外部只能访问对象的公有部分,不能直接访问对象的私有部分。
4)、继承
继承是一个类可以获得另一个类的特性的机制,继承支持层次概念,低层的类中需定义它的特定特征,而共享高层类中的特征。
5)、多态性
不同的对象可以调用相同名称的函数,但可导致完全不同行为的现象称为多态性。利用多态性,程序中只需进行一般形式的函数调用,函数的实现细节留给接受函数调用的对象。
五、使用类和对象
1)、使用String类。
对象使用自己的成员函数的方法是通过”.“运算符,来实现的,其格式如下:
对象名.成员函数
#include <iostream>
#include <string> //使用string类需要包含这个类的头文件
using namespace std;
void main(){
string str1 = "my name is zhangsan"; //常量初始化方式一
string str2("my age is 20"); //常量初始化方式二
char c = str1[0];
cout << "str1的长度是:" << str1.size() << endl;
//str1的长度是:14
cout << "str1的第一个字符是:" << c << endl;
//str1的第一个字符是:m
cout << "please input a word:" << endl;
cin >> str1;
//程序接收键盘输入的一个单词给str1,这里就改变了str1的内容,输入:hello
cout << "现在str1的长度是:" << str1.size() << endl;//现在str1的长度是:5
cout << str1 + " " + str2 << endl;
//string类可以使用+号将字符串进行拼接,拼接之后:hello my age is 20
}
2)、使用String类的成员函数实例
成员函数:substr,find
#include <iostream>
#include <string> //使用string类需要包含这个类的头文件
using namespace std;
//使用string类的典型成员函数
void main(){
//string类的成员函数substr
string str1 = "my name is tom";
string str2 = str1.substr(3,4); //从下标为3(实际第4个位置)开始截取4个字符
cout << str2 << endl;
//截取的字符串是:name
string str3 = "我的名字是tom";
string str4 = str3.substr(3,3);//中文一个字符占用三个字节,这里从下标为3(实际是第4个字节)开始截取3个字节(即一个字符)
cout << str4 << endl;
//截取的字符串是:的
string str5 = str1.substr(11,10); //截取的长度大于字符串长度时,会自动截取到字符串末尾
cout << str5 << endl;
//截取的字符串是:tom
//string类的成员函数find
int index1 = str1.find("my");
cout << "my在str1中的位置索引是:" << index1 << endl;
//my在str1中的位置索引是:0
int index2 = str1.find("my",2); //从下标为2的地方开始查找my字符串,查找不到时返回值 为-1
cout << "my在str1中的位置索引是:" << index2 << endl;
//my在str1中的位置索引是:-1
//string类的辅助功能getline
string inputStr;
getline(cin,inputStr,'\n'); //可以从cin流中读取一行的字符串给string类的对象
cout << "刚刚输入的字符串是:" << inputStr << endl;
//刚刚输入的字符串是:这是一个测试
}
① void是无类型标识符,只能用来声明函数的返回值类型,不能用来声明变量;
② C++标准限定int和short至少要有16位,而long至少32位,short不得长于int,int不得长于long,int使用4字节;
③ 地址运算符"&"用来获取对象存储的地址,存储地址用16进制表示,例如下:
//声明并定义一个对象,使用"&"来获取对象的存储地址并输出
void example1(){
int x = 50;
cout << &x;//打印结果:0x62ff1c
}
3)、使用complex对象
复数类需要两个初始值:实部和虚部
complex类是一个模板类,可以定义多种数据类型的复数。
使用real和imag成员函数来输出对象的 实部和虚部。
#include <iostream>
#include <complex>
#include <string>
using namespace std;
void main(){
complex <int> num1(2,3);
complex <float> num2(3.5,4.5);
string str1 = "real is ";
string str2 = "image is ";
cout <<str1 <<nun1.real() <<<',' << str2 << <nun1.imag() << endl;
cout <<str1 <<nun2.real() <<<',' << str2 << <nun2.imag() << endl;
/**
* 运行结果:
* real is 2 ,image is 3
* real is 3.5 ,image is 4.5
*/
}
六、string对象数组与泛型算法
string类还有一个swap成员函数。
//使用string对象数组
int main(){
string str1 = "we are here!",str2(str1); //使用str1初始化str2
reverse(str1.begin(),str1.end()); //字符串元素逆向
cout << str1 << endl;
//!ereh era ew
copy(str1.begin(),str1.end(),str2.begin()); //将str1复制到str2
cout << str2 << endl;
//!ereh era ew
reverse_copy(str1.begin(),str1.end(),str2.begin()); //逆向复制str1的内容到str2
cout << str2 << endl;
//we are here!
str1.swap(str2); //将str1的内容与str2的内容进行交换
cout << str2 << endl;
//!ereh era ew
int result = *find(str1.begin(),str1.end(),'e') == 'e'; //查找e在str1中的位置存储的值并跟e进行比对
cout << result << endl;
//1
}