c++学习-下

c++学习-下

  • ```模板类```
  • ```C++堆与栈内存```
  • ```auto类型```
  • ```静态数组array```
  • ```函数指针```
  • ```lambda```
  • ```命名法```
  • ```线程```

模板类

  • 通过模板类,可以使其输出不同的类型(减少重载次数)
    • 事实上,像下例中的 Print 函数只有调用的时候才会构建
    • 可以自动推断类型,也可以像下面那样,通过尖括号内写类型来确定函数类型
template<typename T>
void Print(T value)
{
	cout<<value<<endl;
}
main()
{
	Print("Hello");
	Print(10);
	Print<int>(5);
}
  • 类的模板
    • 在实例化时,可以用尖括号指定类型
template<typename T, int N>
class Example()
{
	private:
		T array[N];
	public:
		int GetSize() const {return array[N]}
}
main()
{
	Example<string,20> e;
	cout<<e.GetSize<<endl;
	cin<<get();
}

C++堆与栈内存

  • ram:随机存储器,是与CPU直接交换数据的内部存储器
  • 栈的分配就是CPU的一条指令,所以栈的分配较快,所以如果可以尽量使用栈的分配
  • 堆(使用new时),先检查空闲列表,再申请内存,最后再记录他们。

auto类型

  • auto类型可以自动推断类型,但是为了代码的可读性,我们一般都还是直接把类型写出来。
  • 但是,当遇到非常长的类型时,我们可以使用auto,如下例。
#include
#include
#include
int main()
{
	std::vector<std::string> fruit;
	fruit.push_back("apple");
	fruit.emplace_back("orange");
	for(std::vector<std::string>::iterator it = fruit.begin(); it != fruit.end(); it++)
		{
			std::cout << it* << std::endl;
		}
	//上面的类型太长了,可以直接这么写
	for(auto it = fruit.begin(); it != fruit.end(); it++)
		{
			std::cout << it* << std::endl;
		}
}

静态数组array

  • 静态数组array是在栈上建立的,而vector是在堆上建立的。
  • array必须要知道其size如:std::array a;
  • array没有额外的性能开销,而且还可以记录数组的大小

函数指针

  • 函数指针是将一个函数赋值给一个变量的方法
int man()
{
	void Print()
	{
		std::cout << "578" << std::endl;
	}
	void(* pt)() = Print(); //这是一个函数指针,pt是名,后面的圆括号是参数变量的类型,但这里是void类型,所以里里面是空的
	//可以直接这样调用Print函数了
	pt();
}
  • 函数指针使得一个函数可以接受另一个函数作为参数,如下例
template<typename T>
void ForEach(std::vetcor<T>& values,void(*func)(int))
	{
		for (int value : values)
		{
			func(value);
		}
	}
int main()
{
	std::vector<int> value = {1,2,3,4,5,6};
	ForEach(value, [](int value){cout<<"value:"<<value<<endl;})
	
}

lambda

  • 像上面的例子里 [ ](int value){cout<<“value:”<
  • 方括号里就是捕获方式,可以输入= 代表值传递、&代表引用,这里是捕获当前作用域里其他变量(当前lambda外的变量),也可以直接输入变量名
  • 但是如果要像上面这样调用这种lambda是不行的,得像下例这样使用functional
#include
template<typename T>
void ForEach(std::vetcor<T>& values,functional<void(int)>& func)
	{
		for (int value : values)
		{
			func(value);
		}
	}
int main()
{
	std::vector<int> value = {1,2,3,4,5,6};
	int a = 7;
	ForEach(value, [a](int value){cout<<"value:"<<a<<endl;})
	
}

命名法

  • 帕斯卡命名法:每个单词首字母大写,中间不能有下划线或空格等,和驼峰的区别是,驼峰的首字母要小写。
  • 蛇形命名法(c++标准库常用):单词小写,中间用下划线连接。

线程

  • 这里举个例子,先设立一个线程,会先阻塞主线程,直到当前线程结束才会继续主线程。
#include
#include
static bool Finished = False;
void DoWork()
{
	using namespace literals::chrono_literals;
	if (!Finished)
	{
		std::cout<<"hello"<<std::endl;
		std::this_thread::sleep_for(1s);//每次打印等待1s	
	}
}
int main()
{
	std::thread worker(DoWork); //这里的 DoWork 是一个函数指针的调用方式
	std::cin.get();
	Finished = True;
	worker.join();   //join函数会一直阻塞主线程,直到 worker 线程内的程序跑完,才会继续主线程
}

你可能感兴趣的:(C++,c++,学习,开发语言)