相较于C++98/03,C++11则带来了数量可观的变化,其中包含了约140个新特性,以及对C++03标准中约600个缺陷的修正,这使得C++11更像是从C++98/03中孕育出的一种新语言。相比较而言,C++11能更好地用于系统开发和库开发、语法更加泛华和简单化、更加稳定和安全,不仅功能更强大,而且能提升程序员的开发效率。
#include
#include
using namespace std;
int main()
{
//内置类型
int arr[] = { 1, 2, 3, 4, 5 };//c++98
int arr1[]{1, 2, 3, 4, 5};//c++11
int x{ 1 };//c++11
int y{ 1 + 2 };//c++11
//动态数组C++98没有
int* arr2 = new int[6]{ 1, 2, 3, 4, 5, 6 };
//容器
set<int> s1{ 1, 2, 3, 4, 5 };
return 0;
}
class Point
{
public:
Point(int x = 0, int y = 0): _x(x), _y(y)
{}
private:
int _x;
int _y;
};
int main()
{
Pointer p{ 1, 2 };
return 0;
}
int main()
{
int a = 10;
//必须知道a的类型,才能auto出c的类型
auto c = a;
c = 12;
cout << c << endl;
return 0;
}
int main()
{
int a = 1;
int c = 2;
decltype(a + c) d = 10;
cout << typeid(d).name() << endl;//int
return 0;
}
#include
using namespace std;
void* fun(size_t size)
{
return malloc(size);
}
int main()
{
//函数的类型
cout << typeid(decltype(fun)).name() << endl;
//函数返回值类型
cout << typeid(decltype(fun(0))).name() << endl;
return 0;
}
using namespace std;
int main()
{
//数组
int arr[] {1, 2, 3, 4, 5};
for (auto& e : arr)
cout << e << " ";
cout << endl;
//容器
vector<int> vt{ 1, 2, 3, 4, 5, 6 };
for (auto& e : vt)
cout << e << " ";
cout << endl;
return 0;
}
#include
using namespace std;
class A
{
public:
A() = default;
//系统默认生成A()
A(int a) : _a(a)
{}
// 禁止编译器生成默认的拷贝构造函数以及赋值运算符重载
A(const A&) = delete;
A& operator=(const A&) = delete;
private:
int _a;
};
int main()
{
A a1(10);
//A a2(a1);//错误
A a;
return 0;
}
注意:
(1).const引用既能引用左值,也能引用右值:
int main()
{
int a = 10;
int& pa = a;
const int& pc = a;
a = 20;
cout << pa << endl;
//int& pb = 20;错误;
const int& pb = 20;//
cout << pb << endl;
const int a1 = 10;
// int& pa1 = a1; //由于a1 为 const int 类型 所以左值引用会出现错误
// pa1 = 20;
cout << a1<< endl;
//cout << pa1 << endl;
return 0;
}
int main()
{
// 10纯右值,本来只是一个符号,没有具体的空间,
// 右值引用变量r1在定义过程中,编译器产生了一个临时变量,r1实际引用的是临时变量
int&& r1 = 10;
r1 = 100;
int a = 10;
//int&& r2 = a; // 编译失败:右值引用不能引用左值
return 0;
}
int main()
{
//s1此时无效
string s1("string");
string s2(move(s1));
string s3(s2);
for (auto& e : s1)
cout << e << " ";
cout << endl;//空的
return 0;
}
Person(Person&& p)
: _name(move(p._name))
, _sex(move(p._sex))
, _age(p._age)
{}
void Fun(int &x){cout << "lvalue ref" << endl;}
void Fun(int &&x){cout << "rvalue ref" << endl;}
void Fun(const int &x){cout << "const lvalue ref" << endl;}
void Fun(const int &&x){cout << "const rvalue ref" << endl;}
template<typename T>
void PerfectForward(T &&t){Fun(std::forward<T>(t));}
int main()
{
PerfectForward(10); // rvalue ref
int a;
PerfectForward(a); // lvalue ref
PerfectForward(std::move(a)); // rvalue ref
const int b = 8;
PerfectForward(b); // const lvalue ref
PerfectForward(std::move(b)); // const rvalue ref
return 0;
}
int main()
{
string s1("hello");
string s2(" world");
string s3 = s1 + s2; // s3是用s1和s2拼接完成之后的结果拷贝构造的新对象
stirng&& s4 = s1 + s2; // s4就是s1和s2拼接完成之后结果的别名
return 0;
}
auto fun = [=, &b](int c)->int{return b += a+ c; };
[] : 扑捉列表;
() : 参数列表;
-> int: 返回值类型;
{} : 函数体.
注意: 在lambda函数定义中**,参数列表和返回值类型都是可选部分**,而捕捉列表和函数体可以为空。因此C++11中最简单的lambda函数为:[]{}; 该lambda函数不能做任何事情。
捕获列表说明:
捕捉列表描述了上下文中那些数据可以被lambda使用,以及使用的方式传值还是传引用。
[var]:表示值传递方式捕捉变量var
[=]:表示值传递方式捕获所有父作用域中的变量(包括this)
[&var]:表示引用传递捕捉变量var
[&]:表示引用传递捕捉所有父作用域中的变量(包括this)
[this]:表示值传递方式捕捉当前的this指针
// lambda表达式:
int main()
{
//最简单的lambda表达式
auto f1 = []{};
int a = 3;
int b = 4;
//省略参数列表
[=]{return a + b; };
//省略返回值类型,
auto f2 = [=,&b](int c){return b = a + c; };
f2(10);
cout << f2(10) << endl;
auto fun2 = [=, &b](int c)->int{return b += a + c; };
cout << fun2(10) << endl;
return 0;
}
class Rate
{
public:
Rate(double rate) : _rate(rate)
{}
double operator()(double money, int year)
{
return money * _rate * year;
}
private:
double _rate;
};
int main()
{
// 函数对象
double rate = 0.49;
Rate r1(rate);
r1(10000, 2);
// lamber
auto r2 = [=](double monty, int year)->double{return monty*rate*year; };
r2(10000, 2);
return 0;
}
实际在底层编译器对于lambda表达式的处理方式,完全就是按照函数对象的方式处理的,即:如果定义了一个lambda表达式,编译器会自动生成一个类,在该类中重载了operator()