您的位置:首页 > 编程语言 > C语言/C++

C++ 11中几个我比较喜欢的语法

2013-01-25 10:16 183 查看
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里面还不支持,无法实现跨平台开发,暂时就不介绍了。

补充:C++ 11中几个我比较喜欢的语法(二)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: