在C语言中,我们通常用char类型定义字符数组来对字符串进行操作,其中需要用到各种复杂的函数。但在C++中,为了简化对字符串的操作,我们引入了一个新的变量类型:string类型。它是把一整个字符串当做一个变量来处理,而不像char类型,字符串是一组变量。我们只需要在程序开头声明#include <string>就可以使用string类型定义变量。个人认为这是一个非常实用的工具。下面就介绍一下string变量的使用方法:
上图展现的是string变量的初始化方法,非常的简洁明了。
这是string类型的一些常用操作。可以看到我们可以轻松地对字符串进行连接、替换、判断、计算长度等。这里需要注意的是,s1+s2这个操作方法,不能用于两个直接用双引号表示的字符串连接,比如,cout << "Hello" + "World" << endl; C++不支持这样的字符串连接,这样的写法是非法的。
下面这段代码,展现了string变量的用法:
#include <iostream>
#include <string>
using namespace std;
int main(void)
{
string name;
cout << "Please enter your name:" << endl;
getline(cin, name);
if (name.empty())
cout << "input NULL.." << endl;
else
{
cout << "Hello " + name + "!" << endl;
if (name == "VIP of Jianshu")
cout << "You are an administrator!" << endl;
cout << "The length:" << name.size() << endl;
cout << "The first letter:" << name[0] << endl;
}
system("PAUSE");
return EXIT_SUCCESS;
}
这个程序实现的功能是:1.提示用户输入姓名;2.接收用户输入;3.向用户问号;4.告诉用户名字的长度;5.告诉用户名字的首字母;6.如果用户直接输入回车,则提示输入为空;7.如果用户输入的是“VIP of Jianshu”,那么提示用户是管理员。在这段程序里面,我们用到了字符串的输入输出,字符串对比,计算字符串长度,提取字符串中单个字符等操作。注意到输入字符串时,我们并没有直接使用cin而是用了getline函数,这是因为我们需要检测用户是否输入了回车,而cin并不支持接收输入的回车,所以要用getline来接收。
有了string变量,等于有了一个强有力的工具,在之后的C++学习中会经常用到string变量。接下来为大家介绍C++中数据的封装。
在我发的上一篇有关类和对象的博客中,我都是直接用对象名.成员名来对public中的成员进行访问。这样做虽然很简单,也很明了,但是这违背了C++“面向对象”的思想。我们要把“谁,做什么”这一思想进行到底。这样一来,我们就需要把在主函数里直接访问变量转换为调用成员函数来对变量进行操作,所有的方法都通过调用自己的函数来完成。此时,我们就需要将数据成员“封装”起来。接下来看一下如何用代码实现封装数据。
class Dog
{
public:
void setName(string _name) { name = _name; }
string getName() { return name; }
private:
string name;
int age;
};
在这段代码中,我们将数据成员name和age都用private修饰,而在public中,我们定义了两个函数,分别用于设置名字和读取名字。有人会问,这样对数据进行封装,有什么实际意义上的好处吗?有。比如,如果不进行封装,直接对变量进行赋值,那么可能会出现非法,像名字输了1000个字符,或者年龄输入了1000岁等等,把数据封装起来,我们就可以通过限制成员函数形参的取值范围来对输入进行限制。
另外,我们可能希望某些数据成员只能被读取而不能被写入,这一点也可以体现封装的优点。
class Student
{
public:
int getScore()
{
return m_iScore;
}
private:
int m_iScore;
};
这样我们就实现了对学生成绩m_iScore的“只读不写”。
接下来,我们通过一个完整的程序来看一下数据封装的具体应用:
我们需要定义一个学生“Student”类,里面需要包含名字、性别、学分(只读),还有一个“学习”的方法。下面来看代码
#include <iostream>
#include <string>
#include <stdlib.h>
using namespace std;
class Student
{
public:
void setName(string _name)
{
m_strName = _name;
}
string getName()
{
return m_strName;
}
void setGender(string _gender)
{
m_strGender = _gender;
}
string getGender()
{
return m_strGender;
}
int getScore()
{
return m_iScore;
}
void initScore()
{
m_iScore = 0;
}
void study(int _score)
{
m_iScore += _score;
}
private:
string m_strName;
string m_strGender;
int m_iScore;
};
int main(void)
{
Student stu;
stu.setName("Zhangsan");
stu.setGender("Male");
stu.initScore();
stu.study(2);
stu.study(7);
cout << stu.getName() << " " << stu.getGender() << " " << stu.getScore() << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
以setName和getName为例,通过setName将输入的数据传给形参_name,然后把_name的值赋给数据成员m_strName,在读取的时候,通过将其返回到getName读取数据。对性别、学分的操作也是如此。
在这里我们加入了一个初始化函数initScore,它是将m_iScore的初值赋为0,如果不初始化变量可能就会让m_iScore在int型变量范围内随机取值,造成结果错误。
之后的study函数是一个“学习”的方法,函数的功能是将输入的学分加到原有的学分上。
如图所示为输出结果:
还有一点需要注意,就是数据成员的命名规范,我们一般将数据成员命名为m_+类型+名称,如m_strName。并不是说不这样命名程序就无法运行,而是规范了变量名称,以后在写程序时会更加清晰,知道这个变量是干嘛的,从哪来的,不会乱。所以个人认为规范化命名是很重要的。
以上就是本文的全部内容。下一章将介绍类外定义和内联函数的知识。