C++ 11中几个计较好的语法

2013年8月28日 由 Creater 留言 »

C++11的标准已经确定,除了增加了不少库函数外,在语法方便也得到了许多增强。其中如下几个语法就是我比较喜欢的:

自动类型推导auto

现在c++终于在编译器级别支持类似C#的var关键字了,在c++里的关键字是auto,基本用法如下:

auto i = 0; //int
auto c = ‘c’; //char
auto s = “hello world”; //const char*

auto关键字的一个很直观的好处是我们可以简化stl容器遍历里的那个iterator了:

for(auto it = v.begin(); it != v.end(); it++)
{
cout << *it << endl; } Lambda 表达式 Lambda 表达式的主要用来构造匿名函数,它可以替换绝大部分场景的仿函数(感觉把刚刚引入STL库的std::bind也顺手给秒了),并且有更好的可读性。一个简单的示例如下: auto k = [](int x, int y) { return x + y; }; cout << k(3, 2) << endl; 可以看到,它的基本语法形式为: [capture] (parameters) {body},后两部分和C#的匿名函数的语法非常,但最前面的 [capture] 的作用是什么呢?它是用来引用表达式外的局部变量的,例如: int i1 = 0, i2 = 3; auto k = [&i1, &i2] () { i1 = 3; i2 = 5; }; cout << i1 << " " << i2 << endl; 除了是前面所述的普通局部变量外,还可以是如下特殊符号: = 所有局部变量,以按值的方式传递(包括this指针) & 所有局部变量,以按引用的方式传递(包括this指针) this this指针 Range-based for-loop 这个其实就是类似C#里面的foreach,不过它并没有引入新关键字,而是直接用的for int p[8] = {2, 3, 5, 7, 11, 13, 17, 19}; for (auto& i: p) { printf("%d ", i); } 除了支持数组外,它也支持stl中的迭代器遍历,for_each函数基本上可以下岗了。至于它的原理,可以参考这篇文章。 枚举类 在C语言中,枚举等同于一个数字常量,编译器并没有对它做过多的处理,在C++11中,引入了enum class以替换枚举,它的定义方式如下: enum class Color { Red, Blue}; enum class Fruit { Banana, Apple}; 除了多加了一个class外,没有别的变化,但它定义的枚举功能和C#中的枚举相似。和C语言的传统枚举相比,主要有如下两个区别: 强类型的语法检查 枚举名称只需要在class范围内唯一 强类型的语法检查可以有效防止枚举之间的非法转换和比较,Color::Red == Fruit::Banana之类的判断无法编译通过。 而枚举名称只需要在class范围内唯一则有效缩短了枚举的长度,对于Color枚举,在C语言中,为了防止歧义和命名冲突,往往需要定义为Color_Red、Color_Blue的形式。 静态断言static_assert 静态断言主要提供了在代码中实现编译期可以确定的断言,如果出错则直接以编译错误的形式显示出来,从而加强程序的健壮性。这个其实就是以前的boost.static_assert,不过在编译器的支持下变得更加友好了。示例如下: static_assert(sizeof(int) == 4, "int needs to be 4 bytes to use this code"); 密闭类和密闭方法 C++11中也引入了类似C# seal关键字的方式实现密闭类和密闭方法,以阻止对象继承、方法重载。不过它的关键字是final,和java类似。 final类 class Base final { }; class Derived : public Base //继承密闭类,语法错误 { }; final方法 class Base { virtual void A() final; }; class Derived : public Base { virtual void A(); //重写密闭方法,编译出错 }; 显式覆盖 对于虚函数的重写,在c++ 11中可以通过关键字显式覆盖,从而获得更严格的语法检查。 class Base { virtual void A(float=0.0); virtual void B() const; virtual void C(); void D(); }; class Derived: public Base { virtual void A(int=0) override; //定义不一致,编译错误 virtual void B() override; //返回类型不是const,编译错误 virtual void C() override; //正确 void D() override; //不是虚函数,编译错误 }; PS:我倒觉得这个语法检查应该默认就加上,通过关键字显式去掉检查,而不是像这样显式打开检查。万恶的向上兼容呀。 其它 其它还有几个语法我也很喜欢,如取消字符串转义、委托构造函数、deleted和defaulted成员函数、统一的初始化语法等,但这些在VC里面还不支持,无法实现跨平台开发,暂时就不介绍了。

广告位

发表评论

你必须 登陆 方可发表评论.