C++ 模板初阶和string(1)

文章目录

  • 1.模板
  • 2.STL简介
    • [2.1 STL的版本](#2.1 STL的版本)
    • [2.2 STL的六大组件](#2.2 STL的六大组件)
  • 3.string(1)
    • [3.1 C语言中的字符串](#3.1 C语言中的字符串)
    • [3.2 string::string](#3.2 string::string)
      • [1.default (1) `string();`](#1.default (1) string();)
      • [(2).copy (3)substring](#(2).copy (3)substring)
      • [(5). from buffer](#(5). from buffer)
      • [(6) fill constructor](#(6) fill constructor)
    • [3.3 string::operator[]](#3.3 string::operator[])

在模板之前,C语言和C++可能差距感觉不是很大,而模板之后,区别就很大了

1.模板

C++由于函数可以重载,所以有以下函数:

cpp 复制代码
void Swap(int left, int right)
{
	int temp = left;
	left = right;
	right = temp;
}

void Swap(double left, double right)
{
	double temp = left;
	left = right;
	right = temp;
}

void Swap(float left, float right)
{
	float temp = left;
	left = right;
	right = temp;
}

但是这几个函数相差不大,也就可以用模板写出来:

cpp 复制代码
template<class T> //也可以用typename来定义
void Swap(T& x, T& y)
{
	T temp = x;
	x = y;
	y = temp;
}

函数模板是一个蓝图,它本身并不是函数,是编译器用使用方式产生特定具体类型函数的模具。 所以其实模板就是将本来应该我们做的重复的事情交给了编译器

cpp 复制代码
template<class T>
T func(const T& x1, const T& x2)
{
	return x1 + x2;
}

int main()
{
	int i = 0;
	int j = 2;
	double m = 1.2;

	cout << func(i, j) << endl;

	//推导实例化  (通过实参传给形参,推导出结果)
	cout << func(i, (int)m) << endl;            //1
	cout << func((double)i, m) << endl;         //1.2

	//显示实例化  (显示T可类型到底是什么)
	cout << func<int>(i, m) << endl;            //1
	cout << func<double>(i, m) << endl;         //1.2
	
}

当然也可以定义两个

cpp 复制代码
template<class T1,class T2>
T1 Add(const T1& x,const T2& y)
{
	return x + y;
}

int main()
{
	int i = 0;
	int j = 2;
	double m = 1.2;

	cout << Add(i, j) << endl;

	//推导实例化  (通过实参传给形参,推导出结果)
	cout << Add(i, m) << endl;            //1
	cout << Add(m, i) << endl;            //1.2


}

如果函数的模板同时存在,那么优先调用函数,因为模板需要加工而函数可以直接调用

下面我们用C++来实现栈:

cpp 复制代码
template<class T>
class Stack
{
public:
	Stack(int n = 4)
		:_array(new T[n]),
		_size(0),
		_capacity(n)
	{}

	~Stack()
	{
		delete[] _array;
		_size = 0;
		_capacity = 0;
	}
	void Push(const T& x);
private:
	T* _array;
	size_t _capacity;
	size_t _size;
};

//申明和定义分离
template<class T>
void Stack<T>::Push(const T& x)//模板要加引用,数据不改变加const,减少拷贝
{
	if (_size == _capacity)
	{
		//扩容
		T* tmp = new T[_capacity * 2]; //申请新空间
		memcpy(tmp, _array, sizeof(T) * _size);//拷贝原来数据
		delete[]_array; //释放旧空间

		_array = tmp;
		_capacity *= 2;
	}
	_array[_size] = x;
	_size++;
}

那我们在C语言中也可以改typedef来实现放不同类型的数据

但是模板就可以实现同时创建不同类型的栈:

cpp 复制代码
int main()
{
	//类模板都是显示实例化
	Stack<int> st1;
	st1.Push(1);
	st1.Push(1);
	st1.Push(1);
	st1.Push(1);
	
	Stack<double> st2;
	st2.Push(1.1);
	st2.Push(1.1);
	st2.Push(1.1);
	return 0;
}

2.STL简介

由于C语言没有模板所以写出的东西不能通用,而C++可以让模板通过实例化实现函数通用

2.1 STL的版本

  • 原始版本

​ Alexander Stepanov、Meng Lee 在惠普实验室完成的原始版本,本着开源精神,他们声明允许 任何人任意运用、拷贝、修改、传播、商业使用这些代码,无需付费。唯一的条件就是也需要向原 始版本一样做开源使用。 HP 版本--所有STL实现版本的始祖。

  • P. J. 版本

​ 由P. J. Plauger开发,继承自HP版本,被Windows Visual C++采用,不能公开或修改,缺陷:可读 性比较低,符号命名比较怪异。

  • RW版本

​ 由Rouge Wage公司开发,继承自HP版本,被C+ + Builder 采用,不能公开或修改,可读性一 般。

  • SGI版本

​ 由Silicon Graphics Computer Systems,Inc公司开发,继承自HP版 本。被GCC(Linux)采用,可 移植性好,可公开、修改甚至贩卖,从命名风格和编程 风格上看,阅读性非常高。我们后面学习 STL要阅读部分源代码,主要参考的就是这个版本。

2.2 STL的六大组件

空间配置器其实就是一个内存池

3.string(1)

使用时要包含<string>头文件

3.1 C语言中的字符串

C语言中,字符串是以'\0'结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列 的库函数,但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户 自己管理,稍不留神可能还会越界访问。

3.2 string::string

下面是这几个的使用方法:

1.default (1) string();

(2).copy (3)substring

copy (2) string (const string& str);
substring (3) string (const string& str, size_t pos, size_t len = npos);

npos是静态成员变量

它的值是整形的最大值

(5). from buffer

复制前面n个字符

(6) fill constructor

创建一个由n个字符的字符串

3.3 string::operator[]

其内部实现与下面相似:

cpp 复制代码
class string
{
public:
	char& operator[](size_t _i)
	{
		assert(_i < _size);
		return _str[_i];
	}
private:
	char* _str;
	size_t _size;
	size_t capacity;
};

直接返回的是引用,那么我们就可以对字符串的任意位置进行修改了

相关推荐
osir.24 分钟前
2025天梯训练1
c++·多关键字最短路
Zach_yuan33 分钟前
list的模拟实现
c++·list
胡桃不是夹子44 分钟前
学会了蛇形矩阵
c++·算法·矩阵
今天也想MK代码1 小时前
rust编程实战:实现3d粒子渲染wasm
开发语言·rust·wasm
结衣结衣.1 小时前
【Qt】自定义信号和槽函数
开发语言·c++·qt·c++11
尘鹄1 小时前
一文讲懂Go语言如何使用配置文件连接数据库
开发语言·数据库·后端·golang
qq_433554542 小时前
C++ 二叉搜索树代码
开发语言·c++·算法
好看资源平台2 小时前
手写识别革命:Manus AI如何攻克多语言混合识别难题(二)
开发语言·人工智能·php
Hopebearer_2 小时前
vue3中ref和reactive的区别
开发语言·前端·javascript·vue.js·前端框架·ecmascript
JuicyActiveGilbert2 小时前
【C++设计模式】第九篇:装饰器模式(Decorator)
c++·设计模式