清华大学《C++语言程序设计基础》线上课程笔记05---vector对象,对象的复制与移动,string类

vector 对象

C++标准库中的一个类模板

  • 封装任何类型的动态数组,自动创建和删除。
  • 数组下标越界检查。
  • 将动态数组封装成类的知识点中封装的ArrayOfPoints也提供了类似功能,但只适用于一种类型的数组。
 vector<元素类型> 数组对象名(数组长度);
 vector<int> arr(5)   //建立大小为5的int数组

1.与一般数组不同,vector数组对象名不表示数组首地址;
2.可以用size函数获得vector数组的长度

unsigned n;
cin>>n;
vector<double> arr(n); 
for (unsigned i = 0; i < n; i++)
    cin >> arr[i];    //下标读取,因为Vector类中重载了下标运算符

cout << "Average = " << average(arr) << endl;

//计算数组arr中元素的平均值
double average(const vector<double> &arr)  //常引用
{
double sum = 0;
for (unsigned i = 0; i<arr.size(); i++)  //size函数的使用
sum += arr[i];
return sum / arr.size();
}

基于范围的 for 循环配合 auto 举例

#include <vector>
#include <iostream>
int main()
{
std::vector<int> v = {1,2,3};
for(auto i = v.begin(); i != v.end(); ++i)  //.begin()和.end()取到迭代器的首尾地址
    std::cout << *i << std::endl;
    
for(auto e : v)  //适用于各种容器
    std::cout << e << std::endl;
}

对象复制与移动

深层复制

  • 当被复制的对象数据成员是指针类型时,不是复制该指针成员本身,而是将指针所指对象进行复制;
  • 需要手写复制构造函数.
class ArrayOfPoints { //动态数组类
public:
ArrayOfPoints(int size) : size(size){  //构造函数
points = new Point[size];  //创建动态数组
}

~ArrayOfPoints() {  //析构函数
delete[] points;
}

private:
Point *points; //指向动态数组首地址
int size; //数组大小
}

ArrayOfPoints::ArrayOfPoints(const ArrayOfPoints& v) {
size = v.size;
points = new Point[size];   //重新申请动态分配
for (int i = 0; i < size; i++)
points[i] = v.points[i];             //挨个复制
}

移动构造(C++11)

将即将消亡的源对象(左值)资源的控制权全部交给目标对象,无需重新申请内存分配

class_name ( class_name && ) 
注:&&是右值引用,函数返回的临时变量是右值
class IntNum {
public:

IntNum(int x = 0) : xptr(new int(x)){ //构造函数
cout << "Calling constructor..." << endl;}

IntNum(const IntNum & n) : xptr(new int(*n.xptr)){//复制构造函数
cout << "Calling copy constructor..." << endl;}

IntNum(IntNum && n): xptr( n.xptr){ //移动构造函数
n.xptr = nullptr;
cout << "Calling move constructor..." << endl;}

~IntNum(){ //析构函数
delete xptr;
cout << "Destructing..." << endl;}

private:
int *xptr;
};

//返回值为IntNum类对象
IntNum getNum() {
IntNum a;
return a;}

int main() 
{   cout << getNum().getInt() << endl; return 0;
}

字符串

用字符数组存储字符串(C 风格字符串)

char str[8] = { ‘p‘, ‘r‘, ‘o‘, ‘g‘, ‘r‘, ‘a‘, ‘m‘, ‘\0‘ };
char str[8] = "program";
char str[] = "program";

string 类

  • 使用字符串类string表示字符串;
  • string实际上是对字符数组操作的封装.
string s1;
string s2 = “abc”;
string s3 = s2; 

常用操作
s + t 将串s和t连接成一个新串
s = t 用t更新s
s == t 判断s与t是否相等
s != t 判断s与t是否不等
s < t 判断s是否小于t(按字典顺序比较)
s <= t 判断s是否小于或等于t (按字典顺序比较)
s > t 判断s是否大于t (按字典顺序比较)
s >= t 判断s是否大于或等于t (按字典顺序比较)
s[i] 访问串中下标为i的字符

例:
string s1 = "abc", s2 = "def";
string s3 = s1 + s2; //结果是"abcdef"
bool s4 = (s1 < s2); //结果是true
char s5 = s2[1]; //结果是‘e‘‘

输入整行字符串

" cin>>..."读取到空格时会停止录入字符串

此时,可以

#include<string>  

使用getline()函数
可以用第三个参数设置字符串结束的分隔符

#include <iostream>
#include <string>       //需要包含该头文件
using namespace std;
int main() {
for (int i = 0; i < 2; i++)
{   string city, state;
    getline(cin, city, ‘,‘);//第三个参数可以设置字符串结束的分隔符
    getline(cin, state);    //默认是换行符结束
    cout << "City:" << city << “ State:" << state << endl;
}
return 0;
}

清华大学《C++语言程序设计基础》线上课程笔记05---vector对象,对象的复制与移动,string类

上一篇:django启动服务时报错:RuntimeError: Model class index.models.User doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.


下一篇:饭来了小组Alpha冲刺阶段记录