下面是总结的c++ 11新特性例子
#include <memory>
#include <map>
#include <vector>
#include <deque>
#include <string>
#include <iostream>
#include <iomanip>
#include <array>
#include <forward_list>
using namespace std;
/*
c++98中,只能对数组和struct采用'{}'列表初始化(不是构造对象),c++11将这功能扩展了.
*/
//use initialization list not only is object can use
void test1()
{
int a{49};
int a1 = { 40 };
double b{8.99999};
//int s = { b };//it is error if lose data
}
//newly increase key word
void test2()
{
int* p = nullptr;//null point
// constexpr int a = 89;//word fase expression vs2013 no suport
auto s = 8;
auto t = 9.9; //auto key word means automatically declare types based on values
int de = 0;
decltype(de) dou; //decltype key word used to get a type
int c{ 34 }, c1{5};
// decltype(*p) i = NULL;//failed. because experssion is a dereference(解引用)operation,get a object of p point,is a reference.need set value.
decltype(*p)i = c;
decltype((c)) i1 = c1;//if a expression include '()' ,it is a dereference(解引用)
using SI = double; //using aslias as same as typedef
SI g = 9.3;
}
void test3()
{
string s = "abcdefghijk";
for (auto v : s)
{
cout << v << endl;
}
int a[8] = {1,2,3,4,5,6,7,8};
for (auto v : a)
{
cout << v << endl;
}
}
void t(initializer_list<string>il)
{
for (auto v : il)
{
cout << v << endl;
}
}
void test4()
{
initializer_list<string>st = { "1", "2", "3", "s" }; //newly increase templete type as same as vector,but only is const data in initializer_list
// initializer_list element amount is can not change after definition.
t(st);
vector<string> s2 { "a", "b", "c" };//vector also have list initializtion.
int a;
a = {4};//use '{}' to assignment value,compile fails if value partial lose.for example: double to int type
s2 = { "f", "g", "h" };//c++ 11 suport use '{}' to set value.
for (auto v : s2)
{
cout << v << endl;
}
}
//c++ 11默认函数控制"=default","=delete"
class testfault
{
public:
int s;
testfault() = default;//"=default" 函数特性仅仅适用于特殊成员函数,默认构造、析构函数,拷贝构造、赋值运算符。
//"=default"表示该函数为默认构造,且无参数。并且不能再次实现,就是默认实现的构造函数
//"=default"在类里表示inline,在类外表示非inline.
//testfault(int a) = default;//error
testfault(const testfault& x) = delete;//"=delete"声明拷贝构造函数被禁用。
testfault& operator=(const testfault& x) = delete;//声明赋值运算操作符被禁用
};
//testfault::testfault()==default;
class sales_data
{
public:
int a;
int b;
int c;
//非委托构造函数
sales_data(int a, int b, int c) :a(a), b(b), c(c)
{}
//构造函数委托给其他构造函数就是委托构造函数。c++ 11新特新,不然只有在调用直接基类才能这么用
sales_data() :sales_data(3, 2, 1)
{
cout << "delegate" << endl;
}
};
void test5()
{
//新增容器 array(数组)、forward_list(单向链表)
array<int, 5>s = { 1, 1, 2, 3, 4 };//array 不支持添加和删除元素,容器都支持列表初始化'{}'
array<int, 5>s1 = {3};
forward_list<int>f;
forward_list<int>::iterator it = f.begin();
f.emplace_after(it, 6);//emplace_after对应push_back;emplace、emplace_front类似
swap(s, s1);//非容器方法swap交换两个容器内容
deque<int>d={5};
d.shrink_to_fit();//c++ 11: shrink_to_fit用来要求容器退回不要的空间,只适用于vector、deque、string.
map<int, string>m{ { 1, "1" } };//也支持初始化列表'{}'
}
//lambda表达式,也是匿名函数
void test6()
{
int a=0, b=1;
auto foo = [a]()->int{return a; };
foo();
int(*f)(int a);
f = [](int a)->int{return a; };
}
//右值引用 c++11
void test7()
{
int &&sr = 9;//字面常量是右值,使用右值引用
int sl = 8;
sr = std::move(sl);//move 标准库函数,将右值引用绑定到左值,move告诉编译器,我们有一个左值,
//但我们希望像使用右值一样使用它。调用move就意味着,当move后,除了对这个
//左值进行赋值和销毁外,我们不将使用它。
//因此不要随意使用移动操作,我们必须确保没有其他用户使用该左值。
}
//移动构造函数
class testMoveCon
{
public:
string s;
testMoveCon(testMoveCon&& a);//移动构造函数与拷贝构造函数不同,它不会分配空间接管原对象空间
testMoveCon() = default;
testMoveCon operator=(testMoveCon&& b);//移动赋值运算符
};
testMoveCon::testMoveCon(testMoveCon&& a)
{
this->s = a.s;
a.s ="";
cout << "move " << endl;
}
testMoveCon testMoveCon::operator = (testMoveCon&& b)
{
if (this != &b)
//释放已有元素
this->s = b.s;//接管资源
b.s = nullptr;//将b置位可析构状态
return *this;
}
//智能指针
void test8()
{
shared_ptr<sales_data> sd = make_shared<sales_data>();//make_shared为一函数模板,return shared_ptr对象
unique_ptr<sales_data> up(new sales_data());//unique_ptr:同一时刻只能有一个unique_ptr指向一个对象,当unique_ptr销毁时,所指对象也销毁。
//unique_ptr<sales_data> up1 = new sales_data();//error:unique_ptr不支持拷贝构造函数,不支持赋值 up1 = up;
weak_ptr<sales_data> wp = sd;//weak_ptr 是弱指针,这个例子是与shared_ptr共享一个对象,但是weak_ptr并不会增加shared_ptr的引用计数,同时,当
//weak_ptr销毁的时候,它所指的对象是不会销毁的。
}
class nodervied final //用final修饰的类可防止继承,nodervied不能被继承
{
};
void test9()
{
tuple<int, char, string>s;//tuple:c++11新增类型,它不想pair,有两个成员,它的成员是任意的。
tuple<int, char>s1;//等等
//bitset<32>bitvec(1U);//bitset是一个类模板,它类似array,声明它时,需声明它包含多少个二进制位。
//bitset<32>bitv("1100");//可以用string来初始化bitset
}
//enum 提前声明,之后定义的时候必须与声明匹配。且不限定作用域的必须指定成员类型如:
//enum intvalue:long long; 限定作用域的默认是int;
/*
分限定作用域如:enum class intvalue;
*/
//noexcept 说明
class exception1
{
public:
//void fun() noexcept; vs2013 NOT SUPORT ,表示fun()方法不会抛出异常,这里noexcept是异常说明
void fun(int a) throw();//throw()和noexcept一样,表示该方法不会抛出异常
//注意举例说明一下:如,当在函数后加上throw(int),表示该函数可能抛出int异常或不抛出异常,该函数内部对外抛出的
//异常只能int类型,否则程序就会调用unexsetpion()函数,退出。且外面不能catch到该函数除了int类型外的其他异常。
//throw(int,char)表示抛出的异常可能是int或者char类型
//void pre(int a) noexcept(true);//noexcept(true)表示可能抛出异常,noexcept(false)表示不抛出异常。
};
int main()
{
exception1 ggg;
// ggg.fun(5);
test1();
// test3();
test4();
testfault S;
sales_data s;
test7();
testMoveCon m;
testMoveCon m1(std::move(m));
system("pause");
return 0;
}