C++ 11新特性之语法甜点3

简介: C++ 11新特性之语法甜点3

概述

C++ 11中引入了许多简化编程工作的语法上的新特性,我们暂且美其名曰:“语法甜点”。书接上篇,我们继续介绍C++ 11中的这些“语法甜点”,也是第三篇关于“语法甜点”的文章。

语法甜点11:非成员的begin和end

在C++ 03中,标准容器都提供了begin和end成员函数。但对于普通数组,则只能使用不同的写法。

vector<int> v;
int a[100];
sort(v.begin(), v.end());
sort(a, a+sizeof(a)/sizeof(a[0]));


为了统一语法,C++ 11提供了非成员的begin和end函数。

vector<int> v;
int a[100];
sort(begin(v), end(v));
sort(begin(a), end(a));


语法甜点12:显式虚函数重载

在引入C++ 11之前,基类和派生类中的虚函数很容易产生错误使用的情况。比如:

1、基类添加了一个虚函数,但该虚函数与派生类中的某个已有普通函数相同。

2、派生类添加了一个普通函数,但该函数与基类中的某个已有虚函数相同。

为了避免这些情况,在C++ 11中可以使用override来显式地表明需要进行虚函数重载。注意:为了保持向后兼容,此功能是选择性的。

class CBase
{
    virtual void SomeFunc(float);
};
class CDerived : public CBase
{
    virtual void SomeFunc(int) override;        // 将产生编译错误
    virtual void SomeFunc(float) override;      // 正确
};


另外,C++ 11中还引入了final指示符,用于防止类或接口被继承。

class  CBase1 final { };
// 将产生编译错误
class CDerived1 : public CBase1 { };
class CBase2
{
    virtual void Func() final;
};
class CDerived2 : public CBase2
{
    // 将产生编译错误
    void Func();
};



语法甜点13:强类型枚举

在C++ 03中,枚举类型不是类型安全的。枚举类型被视为整数,这使得两种不同的枚举类型之间可以进行比较。C++ 03唯一提供的安全机制就是:一个整数或一个枚举型值,不能隐式转换为另一个枚举型值。

在C++ 11中,引入了enum class来声明类型安全的枚举类型。

enum class IColor1 { Red, Blue, Gree=100, Black };


IColor1不能隐式地转换为整数类型,也不能与整数类型比较大小。使用枚举名时,必须明确指定其所属范围,比如:必须使用IColor1::Red,而不能单独使用Red。

在C++ 11中,使用enum class和传统的enum时,还可以指定其所用的数据类型,不指定时默认为int。

enum class IColor2 : unsigned int { Red, Blue, Gree=100, Black };
enum IColor3 : unsigned int { Red, Blue, Gree=100, Black };


另外,enum class IColor1;

enum class IColor2 : unsigned int;

enum IColor3 : unsigned int;C++ 03中,无法对枚举类型进行前置声明。而在C++ 11中,只要是使用了指定数据类型的新式枚举,都可以进行前置声明。

enum class IColor1;
enum class IColor2 : unsigned int;
enum IColor3 : unsigned int;


语法甜点14:模板别名

在C++ 03中,可以使用typedef给模板类指定一个新的类型名称,但却不能给类模板指定别名。比如:

template<typename first, typename second, int third>
class SomeType;
template<typename second>
// 在C++ 03中是不合法的
typedef SomeType<OtherType, second, 5> TypedefName;


为了能够定义类模板的别名,C++ 11允许像下面这样使用using关键字:

template<typename first, typename second, int third>
class SomeType;
template<typename second>
using TypedefName = SomeType<OtherType, second, 5>;


另外,using也能定义一般类型的别名,此时等同于typedef。比如:

typedef void (*Func)(int);
using  Func = void (*)(int);


语法甜点15:无限制的union

在C++ 03中,并非任意的数据类型都能做为union的成员。比如:带有non-trivial构造函数的类型就不能是 union的成员。在C++ 11中,移除了所有对union的使用限制,除了其成员仍然不能是引用类型这种情况。

struct point
{
    point() {}
    point(int x, int y): m_x(x), m_y(y) {}
    int m_x, m_y;
};
union
{
    int a;
    double b;
    // 在C++ 03中不合法;在C++ 11中合法
    point p;
};



备注:C++ 03中不适合做union成员变量的情形有以下几种。

1、类或结构体中含有non-trival的构造函数(拷贝构造函数)、析构函数、拷贝赋值操作符、虚函数等。

2、类的基类和成员变量中含有第1点中所述几个函数。

3、静态变量。

4、变量引用。


相关文章
|
1月前
|
存储 编译器 开发工具
01.C++基础语法
本教程系统讲解C++基础语法,涵盖语言特性、编译器使用、命名空间、头文件、修饰符与关键字等核心内容,助你快速掌握C++编程基础。
216 9
|
7月前
|
编译器 C++ 容器
【c++11】c++11新特性(上)(列表初始化、右值引用和移动语义、类的新默认成员函数、lambda表达式)
C++11为C++带来了革命性变化,引入了列表初始化、右值引用、移动语义、类的新默认成员函数和lambda表达式等特性。列表初始化统一了对象初始化方式,initializer_list简化了容器多元素初始化;右值引用和移动语义优化了资源管理,减少拷贝开销;类新增移动构造和移动赋值函数提升性能;lambda表达式提供匿名函数对象,增强代码简洁性和灵活性。这些特性共同推动了现代C++编程的发展,提升了开发效率与程序性能。
274 12
|
9月前
|
编译器 C语言 C++
☺初识c++(语法篇)☺
☺初识c++(语法篇)☺
|
编译器 程序员 定位技术
C++ 20新特性之Concepts
在C++ 20之前,我们在编写泛型代码时,模板参数的约束往往通过复杂的SFINAE(Substitution Failure Is Not An Error)策略或繁琐的Traits类来实现。这不仅难以阅读,也非常容易出错,导致很多程序员在提及泛型编程时,总是心有余悸、脊背发凉。 在没有引入Concepts之前,我们只能依靠经验和技巧来解读编译器给出的错误信息,很容易陷入“类型迷路”。这就好比在没有GPS导航的年代,我们依靠复杂的地图和模糊的方向指示去一个陌生的地点,很容易迷路。而Concepts的引入,就像是给C++的模板系统安装了一个GPS导航仪
331 59
|
12月前
|
安全 编译器 C++
【C++11】新特性
`C++11`是2011年发布的`C++`重要版本,引入了约140个新特性和600个缺陷修复。其中,列表初始化(List Initialization)提供了一种更统一、更灵活和更安全的初始化方式,支持内置类型和满足特定条件的自定义类型。此外,`C++11`还引入了`auto`关键字用于自动类型推导,简化了复杂类型的声明,提高了代码的可读性和可维护性。`decltype`则用于根据表达式推导类型,增强了编译时类型检查的能力,特别适用于模板和泛型编程。
139 2
|
存储 编译器 C++
【C++】面向对象编程的三大特性:深入解析多态机制(三)
【C++】面向对象编程的三大特性:深入解析多态机制
136 1
|
存储 编译器 C++
【C++】面向对象编程的三大特性:深入解析多态机制(二)
【C++】面向对象编程的三大特性:深入解析多态机制
125 1
|
编译器 C++
【C++】面向对象编程的三大特性:深入解析多态机制(一)
【C++】面向对象编程的三大特性:深入解析多态机制
151 1
C++ 20新特性之结构化绑定
在C++ 20出现之前,当我们需要访问一个结构体或类的多个成员时,通常使用.或->操作符。对于复杂的数据结构,这种访问方式往往会显得冗长,也难以理解。C++ 20中引入的结构化绑定允许我们直接从一个聚合类型(比如:tuple、struct、class等)中提取出多个成员,并为它们分别命名。这一特性大大简化了对复杂数据结构的访问方式,使代码更加清晰、易读。
168 0
|
存储 编译器 C++
【C++】面向对象编程的三大特性:深入解析继承机制(三)
【C++】面向对象编程的三大特性:深入解析继承机制
173 0