1.断言是将一个需要为真的表达式放在语句中,在debug模式下检查一些逻辑错误的参数,C++中使用assert需要使用
void fun(int a[],int n)
{
assert(n>0);
//dosomething;
}
这样就可以检查n<=0的情况,如果遇到这种情况,程序会调用abort()函数而终止。
C++11提供了static_assert断言,它的函数原型接受两个参数,一个是断言表达式,一个是警告信息,可以用字符串表示。
static_assert(sizeof(int)==8,”64-bitmachine should follow this”);
int main()
{
return 0;
}
可见,static_assert()比assert提供了更多的信息。另外,static_assert()用于在编译期做断言判断,而assert()用于在运行期间做断言判断。
2.__func__是C++99标准中预定义的标识符,功能是返回所在函数的名字,C++11标准中,__func__可以用于结构体中,如:
#include
#include
using namespace std;
struct Test
{
Test():name(__func__){}
const char *name;
};
int main()
{
Test t;
cout<
3.委派构造函数
class A
{
public:
A(){init();}
A(int i):x(i){init();}
A(double d ):f(d){init();}
private:
void init();
int x;
double f;
};
上面的代码中,三个版本的构造函数都调用了init()函数,有没有办法简化这段代码呢?
可以使用委派构造函数:
class A
{
public:
A(){init();}
A(int i):A(){x=i;}
A(double d):A(){f=d;}
private:
void init();
int x;
double f;
};
4.初始化列表
#include
#include
using namespace std;
int main()
{
int a[]={1,2,3};
int b[]{1,2,3};
vector c{1,3,5};
return 0;
}
C++11支持这样几种初始化的方式:
赋值符号 如int a=1+2;
赋值符号加上初始化列表 int a={1+2};
圆括号 int a(1+2);
花括号加上初始化列表 int a{1+2}
5.右尖括号的改进
template
classA
{};
vector>v;//c++98编译失败,C++11编译成功
vector > v;//C++98编译成功,C++11编译成功
6.auto类型推导
#include
using namespace std;
int main()
{
auto name=”world\n”;
cout<<”hello ”<
auto会自动推导出name的类型为constchar *,然后在cout语句中输出
基于auto的上述特点,auto可以初始化复杂类型变量,可以支持泛型编程
7.for循环的改进
#include
using namespace std;
void action(int &e)
{
cout<
8.智能指针
C++使用的是auto_ptr,在C++11中它被废弃了,取而代之的是unique_ptr,shared_ptr和weak_ptr,
unique_ptr的缺点是必须独自占有内存,不能直接用=来进行赋值,而且使用move方法赋值之后,指针会失去所有权。
#include
#include
using namespace std;
int main()
{
unique_ptr p1(new int(1));
unique_ptr p2=p1; //编译错,不能直接赋值
unique_ptr p3=move(p1);
cout<<*p3<
shared_ptr是表现的最像指针的智能指针。它使用引用计数来表示当前多少指针指向同一块内存,一个指针被释放,引用计数就会减少1,直到引用计数减少为0时,指针指向的内存才会真正的释放。
weak_ptr是作为shared_ptr的辅助,它本身不会引起引用计数的增加,它可以用来检验share_ptr的有效性。
#include
#include
using namespace std;
void check(weak_ptr &p)
{
shared_ptr t=p.lock();
if(t!=nullptr)
cout<<”ok”< p1(new int(1));
shared_ptr p2=p1;
weak_ptr wp=p1;
check(wp); //ok
p1.reset();
check(wp); //ok
p2.reset();
check(wp);
return 0;
}
9.空指针nullptr
C++98中,空指针NULL是一个宏,类似于#define NULL0的形式,所以NULL本质上是个整型。C++11提出了nullptr代替NULL作为空的指针常量。nullptr相对于NULL有什么优势,可以看下这个函数重载的例子。
void f(int i){}
void f(char *c){}
f(NULL)将会调用f(int)的版本,因为NULL是0
而f(nullptr)将会调用f(char*c),因为nullptr是nullptr_t类型的
nullptr与nullptr_t的关系:nullptr_t是指针类型,nullptr是nullptr_t类型的常量
nullptr_t的性质有:
nullptr_t类型数据可以隐式转换成任意一个指针类型
nullptr_t不能转换为非指针类型,
nullptr_t可以用于关系运算,但不能用于算术运算
#include
#include
using namespace std;
int main()
{
char*p=nullptr; //转换为指针类型
int t=reinterpret_cast(nullptr);//编译出错,nullptr_t类型不能转换为int
nullptr_tptr;
if(ptr==nullptr) //可以用于关系运算
cout<<”nullptr”<
10.lamda函数
#include
using namespace std;
int main()
{
int a=1;
int b=2;
auto fun=[=]()->int{return a+b;};
cout<
auto fun=[=]()->int{return a+b}定义了fun函数,它是lamda函数
lamda函数的定义方法如下:
[capture](parameter list) mutable ->return type {//do something;}
有关各个字段的含义这里不再赘述。
下面是lamda在stl中应用的一个例子:
#include
#include
#include
using namespace std;
inline void cmp(int i)
{
if(i>7)
cout<<"larger than 7"< v(a,a+10);
for(auto it=v.begin();it!=v.end();++it)
{
if(*it>7)
cout<<"largerthan 7"<7)
cout<<"largerthan 7"<
上面的代码遍历一个容器vector,使用了三种方法,一是利用迭代器,逐个判断,二是利用仿函数,三是利用了lamda函数。