c++11新特性标准

本文详细介绍了C++编程语言中的auto特性、迭代器使用、decltype的作用、右值引用、lambda表达式、移动语义、完美转发、可变参数模板以及智能指针(unique_ptr)的使用。
摘要由CSDN通过智能技术生成

c++新特性

auto

auto自动推导变量类型;auto 需要初始化,auto不能定义数组。

//void func(auto x);也是错误的!!!
auto n=10;
auto f=12.8;
auto p=&n;
vector<int>::iterator it;
auto p=it;
auto a=10,b=12;
//auto a=10,n=12.3;不要有二义性会报错!!
//auto x;没有给变量类型 

实际应用的例子!迭代器的使用

#include <iostream>
#include<vector>
int main()
{
	vector<int> v = {1,2,3,4,5};
	// vector<int>::iterator it = v.begin();
	auto it = v.begin();
}

decltype

 	short a=100//两个字节
 	short b=100; //两个字节
 	decltype(a+b) c;//得到int 类型的c
 	int n=0;
 	decltype(n) x;
 	auto x = n;
 	const int &r =n;
 	// decltype(r) y; 会报错因为引用使用的时候必须初始化但是y没有	被初始化。
 	decltype(r) y=n;
 	decltype(Class Student::total)c=0;
 	decltype(stu.name) url = "hello";
	
	函数的用法比较常见
	decltype(func(10)) ret = func(100);

基于范围的for循环

如下所示:

for(declaration:expression)
{
	//循环体
}

其中declaration:定义一个变量,变量类型为要遍历序列中存储元素的类型。可以使用auto关键字
expression:表示要遍历的序列,常见的数组和容器

vector<int> v={1,2,3,4,5};
	for(auto item:v)
	{
		cout<<item<<endl;
	}

列表初始化

初始化const 成员属性。

class Foo
{
	public:
	int _x;
	Foo(int x):_x(x) // 列表初始化 _x = x;
}

使用using 定义 别名

 using db = double;
 typedef void(*function)(int,int); //函数指针类型定义
 using function = void(*)(int,int); // 函数指针类型
map<string,int> m1;

//重定义std::map
typedef std::map<string,int> map_int;
using map_int = std::map<std::string,int>;

final关键字

1.修饰一个类不能被继承
2.

class A final
{
public:
      A(){};
}

override重写

override 直接写在虚函数的末尾,用于检查派生类的重写父类虚函数是否存在

右值引用

左值表示可以获取地址的表达式,他能出现赋值语句左边。
右值表示无法获取地址的对象,有常量值,函数返回值,lambda表达式。
通过右值给临时变量生存周期
右值的生命周期结束,临时对象会被销毁,析构函数被调用

int a;
int b=0;
a=10;//可以获取a的地址,因此为左值。
a = b // a b 都是左值,b的值(0 常量)可以当做左值使用!

右值引用可以修改

int num =10;
// int &&a = num; 右值引用不能初始化左值
int && a=10; 

class AA
{
public:
	int a = 33;

};

AA getintmum()
{

	return AA();
}

int main()
{
	/*ThreadPool tp(4);
	for (int i = 0; i < 8; i++)
	{
		tp.enqueue([i] {
			std::cout << "task:" <<i<< "is running..." <<std::endl;
			std::this_thread::sleep_for(std::chrono::seconds(1));
			std::cout << "task:" << i << "is done..."<< std::endl; 
			});
		
	}*/
	int ii = 3;
	auto f = [ii](const int& no) {
		std::cout << "亲爱的" << no << "号,傻傻鸟" << std::endl;
	};
	AA&& aa = getintmum(); // 通过右值一直给临时变量生存周期
	// aa 对象的生命周期结束,临时对象会被销毁,析构函数被调用
	AA ip = getintmum();
	std::cout << aa.a << std::endl;
	std::cout << ip.a << std::endl;
	return 0;
}

协程

协程的本质是暂停和恢复函数
c++中关键 co_await,co_yield,co_return 三个关键字的其一就是协程。
co_awaut 用于暂停协程直到恢复。

lambda函数使用方法

->void{};
一。参数列表,没有默认参数,所有参数必须有参数名,不支持可变参数。
[] 属于捕获列表 若lamda函数体使用外部参数,必须要把参数放入捕获列表中
通过捕获列表可以访问父作用域中的非静态局部变量,静态局部变量可以直接访问,不能访问全局变量。
捕获列表在书写[]中,与函数参数的传递类似,捕获方式可以是值和引用。
若要修改捕获列表中的值,需要采用引用。
[=] [&] 表示自动捕获变量

int ii = 3;
	auto f = [ii](const int& no) {
		std::cout << "亲爱的" << no << "号,傻傻鸟" << std::endl;
	};

移动语义

move 函数将左值转换为右值

class AA
{
public:
	int* m_data = nullptr; //数据成员,指向堆区资源的指针。
	AA() = default;
	void alloc()
	{
		m_data = new int;
		memset(m_data, 0, sizeof(int));

	}
	AA(const AA& a) // 拷贝构造
	{
		std::cout << "调用构造函数" << std::endl;
		if (m_data == nullptr) alloc();
		memcpy(m_data, a.m_data, sizeof(int));
	}
	AA( AA&& a) // 移动构造
	{
		std::cout << "调用移动构造函数" << std::endl;
		if (m_data != nullptr) delete m_data; // 如果已经分配内存,先释放掉。
		m_data = a.m_data; // 把数据从元对象中拷贝过来
		a.m_data = nullptr;
	}
	AA& operator=(const AA& a)
	{
		std::cout << "赋值构造" << std::endl;
		if (this == &a) return *this;  // 避免自我赋值
		if (m_data == nullptr) alloc(); // 如果没有分配内存,就分配
		memcpy(m_data,a.m_data,sizeof(int)); 
		return *this;
	}
	
	AA& operator=( AA&& a) //移动赋值函数 
	{
		std::cout << "赋值构造" << std::endl;
		if (this == &a) return *this;  // 避免自我赋值
		if (m_data == nullptr) alloc(); // 如果没有分配内存,就分配
		memcpy(m_data, a.m_data, sizeof(int));
		return *this;
	}

	~AA()
	{
		if (m_data != nullptr)
		{
			delete m_data; m_data = nullptr;
		}
	
	}
};

int main()
{
	auto f = [] {
		AA aa;
		aa.alloc();
		*aa.m_data = 8;
		return aa;
	};
	AA a4(f()); // 调用移动构造函数

	AA a2 = std::move(a4);
	return 0;
}

完美转发

  1. 如果模板中函数的参数名书写位T&& 参数名,
    那么函数既可以接受左值引用,也可以右值引用。
    2.提供模板书std::forward(参数),用于转发参数,
    如果参数是右值,转发之后仍是右值引用;如果参数是一个左值,转发之后仍是左值引用。
void func1(int& i)
{
	std::cout << "左值引用" << std::endl;
}
void func1(int&& i)
{
	std::cout << "右值引用" << std::endl;
}

template<typename TT>
void func(TT&& ii)
{
	func1(std::forward<TT>(ii));
}

int main()
{
	int ii = 3;
	func(ii);
	func(8);
	return 0;
}

可变参数模板

void print()
{

}
template <typename T,typename ...Args> // 三个点表示可变参数
void print(T arg, Args...args)
{

	std::cout << "参数" << arg << std::endl; // 显示本次展开的参数
	print(args...);//继续展开参数
}

智能指针

unqiue_ptr 独享他只用的对象,也就是说,同时只有一个unqiue_ptr指向同一个对象,当这个unqiue_ptr指向同一个对象,当这个unqiue_ptr被销毁时,指向的对象也随即被销毁。
包含头文件#include

class AA
{
public:
	std::string m_name;
	AA() { cout << "构造函数" << endl; };
	AA(const string& name) { cout << "构造函数" << this->m_name << endl; };
	~AA() { cout << "调用了析构函数" << endl; };


};


int main()
{
	/*ThreadPool tp(4);
	for (int i = 0; i < 8; i++)
	{
		tp.enqueue([i] {
			std::cout << "task:" <<i<< "is running..." <<std::endl;
			std::this_thread::sleep_for(std::chrono::seconds(1));
			std::cout << "task:" << i << "is done..."<< std::endl; 
			});
		
	}*/

	AA* p = new AA("西施");
	unique_ptr<AA> pu1(p);

	return 0;
}
  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值