一、结构的演化
1、结构发生质的演变
1.1 函数与数据共存
C++允许结构中可以定义函数,这些函数称为成员函数,下面是一个简单的示例:
#include <iostream>
using namespace std;
struct Points{
double x,y;//数据成员
void setXY(double a,double b){//成员函数,用来设置数据成员
x = a;
y = b;
}
void displayXY(){//成员函数,用来按指定格式输出数据成员的值
cout << "成员函数输出成员的值:" << x << "\t" << y << endl;
}
};
int main(){
Points p;//定义对象p
p.setXY(10.5,12.6);//设置对象p的数据成员
p.displayXY();//显示p的数据成员
cout << "直接使用数据成员,成员的值为:" << p.x << "\t" << p.y << endl;//这被称作结构Points的公有性质
/**
* 成员函数输出成员的值:10.5 12.6
* 直接使用数据成员,成员的值为:10.5 12.6
*/
return 0;
}
1.2 封装性
没有使用private定义的成员,默认为public,而私有的数据成员只有通过公有的成员函数才能使用,这就称为数据的封装性
private: double t,w;//私有的数据成员
2、使用构造函数初始化结构的对象
#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 displayXY(){//成员函数,用来按指定格式输出数据成员的值
cout << "成员的值:" << x << "\t" << y << endl;
}
};
int main(){
Points p;//定义对象p
Points p2(22.9,30.5);//定义对象p2并赋初始值
p.setXY(10.5,12.6);//设置对象p的数据成员
cout << "显示p的数据成员:" << endl;
p.displayXY();//显示p的数据成员
cout << "显示p2的数据成员:" << endl;
p2.displayXY();//显示p2的数据成员
/**
* 显示p的数据成员:
* 成员的值:10.5 12.6
* 显示p2的数据成员:
* 成员的值:22.9 30.5
*/
return 0;
}
二、从结构演变成一个简单的类
使用关键字class代替struct,这就是一个标准的类,其他不变,使用上面的代码效果是相同的,说明他们是等价的
class Points{...}
三、面向过程与面向对象
所谓面向过程,就是不必了解计算机的内部逻辑,在把精力主要集中在对如何求解问题的算法逻辑和过程的描述上,通过编写程序把解决问题的步骤告诉计算机。
所谓函数,就是模块的基本单位,是对处理问题的一种抽象,把一切逻辑功能完全独立的或相对独立的程序部分都设计成函数,并让每一个函数只完成一个功能。这样,一个函数就是一个程序模块,程序的各个部分除了必要的信息交流之外,互不影响。相互隔离的程序设计方法就是模块化程序设计方法。
相对于过程,对象是稳定的,将现实世界中客观存在的事物称之为对象。在面向对象程序设计中,不仅可以进行功能抽象,而且能进行数据抽象。对象,实际上是功能抽象和数据抽象的统一。
四、C++面向对象程序设计的特点
1、对象
通过抽象归纳,可以使用对象名、属性和操作三要素来描述对象。对象名用来标识一个具体的对象,用数据来表示对象的属性,用操作来描述对象的动态特征(使用函数实现操作,也称为方法)。数据称为数据成员,函数称为成员函数。
2、抽象和类
抽象是一种从一般观点看待事物的方法,即集中于事物的本质特征,而不是具体细节或具体实现。类模型由类名、一组属性、一组操作3部分组成,类的属性只是性质的说明,对象的属性才是具体的数据。类是一组具有相同的属性和操作的一组对象的集合,类的作用是用来定义对象,而对象是类的一个实例。
3、封装
一个对象的属性和操作是紧密结合的,对象的属性只能由这个对象的操作来存取,对象的操作分为内部操作和外部操作。内部操作只供对象内部的其他操作使用,不对外提供。外部操作对外提供一个消息接口,通过这个接口接收对象外部的消息并为之提供操作服务。简单来说,封装就是把对象的属性和操作结合成一个独立的系统单位,并尽可能的隐藏对象的内部细节。
在类中,封装是通过存取权限来实现的,对象的外部只能访问对象的公有部分,不能直接访问对象的私有部分。
4、继承
继承是一个类可以获得另一个类的特性的机制,继承支持层次概念,低层的类中需定义它的特定特征,而共享高层类中的特征。
5、多态性
不同的对象可以调用相同名称的函数,但可导致完全不同行为的现象称为多态性。利用多态性,程序中只需进行一般形式的函数调用,函数的实现细节留给接受函数调用的对象。
五、使用类和对象
1、使用string类
#include <iostream>
#include <string> //使用string类需要包含这个类的头文件
using namespace std;
int 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
return 0;
}
2、使用string类的典型成员函数实例
#include <iostream>
#include <string> //使用string类需要包含这个类的头文件
using namespace std;
//使用string类的典型成员函数
int 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;//刚刚输入的字符串是:这是一个测试
return 0;
}
3、string对象数组
//使用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
}