C++11特性的学习之融入实际应用(七)

  目录括号内为适合人群,所有库作者的内容暂不做学习,可自行查阅《深入理解C++11:C++11新特性解析与应用》。网盘链接: https://pan.baidu.com/s/1Jf29R7-foOoXJ5UW3mTKVA 密码: 7vgq

目录

1.对齐支持(部分人)
  ①数据对齐
  ②C++11的alignof和alignas
2.通用属性(部分人)
  ①语言扩展到通用属性
  ②C++11的通用属性
  ③预定义的通用属性
3.Unicode支持(所有人)
  ①字符集,编码和Unicode
  ②C++11中的Unicode支持
4.原生字符串字面量(所有人)

1.对齐支持 ^

  

  ①数据对齐 ^

struct  A
{
    char a;
    int b;
};

int main()
{
    cout << sizeof(char) << endl;     //输出:1
    cout << sizeof(int) << endl;      //输出:4
    cout << sizeof(A) << endl;        //输出:8

    //offsetof是用于求类中成员在该类中的偏移量
    cout << offsetof(A,a) << endl;    //输出:0
    cout << offsetof(A, b) << endl;   //输出:4

  从上述代码中可以看出,char类型变量的长度为1字节,int类型变量的长度为4字节,但是结构体的长度却为8,由它们在结构体中的偏移量可以看出,变量a与变量b之间空出了3个字节,这是由于C++中的数据对齐造成的。一般而言,类中对以最大数据长度最大的为对齐方式。

  ②C++11的alignof和alignas ^

  C++11标准中,为了支持对齐,引入了两个关键字:操作符alignof和对齐描述符alignas。

  • 操作符alignof:用于返回类的对齐方式,即对齐值
  • 对齐描述符alignas:用于设置类使用哪种对齐方式
  • struct alignas(32) A
    {
        char a;
        int b;
    };
    
    int main()
    {
        //由于用alignas设置了对齐方式,原本大小为8字节的类A变为32字节了
        cout << sizeof(A) << endl;       //输出:32
        cout << alignof(A) << endl;      //输出:32
    
        //alignas既可以接受常量表达式,也可以接受类型作为参数
        alignas(8) int a;
        alignas(alignof(double)) int b;
    }

      C++11标准中规定了一个“基本对齐值”。一般情况下其值等于平台上支持的最大标量类型数据的对齐值。我们可以通过alignof(std::max_align_t)来查询其值。而像之前我们把对齐值设置为32位的做法称为扩展对齐,这按照C++标准该程序是不规范的,可能会导致未知的编译错误或者运行时错误。

      其余对齐方式有STL库函数(std::align),还有STL库模板类型(aligned_storage和aligned_union)。个人觉得原书籍这里后半部分讲的有错,可自行查阅原书籍P263

    2.通用属性 ^

      

      ①语言扩展到通用属性 ^

      随着C++语言的演化和编译器的发展,人们常会发现标准提供的语言能力不能完全满足要求。于是编译器厂商或组织为了满足编译器客户的需求,设计出了一系列的语言扩展来扩展语法,这些扩展语法并不存在与C/C++标准中。

      扩展语言中比较常见的就是”属性“。属性是对语言中的实体对象(比如函数,变量,类型等)附加一些额外的注解信息。在window平台上,扩展属性关键字为__declspec,我们只需在声明变量时加上:

    __declspec (align(8)) class A{};   //括号内的为属性,这里的align即对齐方式

      微软还定义了很多__declspec属性,如noreturn,oninline,align,dllimport,dllexport等,具体的可自行去了解

      ②C++11的通用属性 ^

      C++11标准中的通用属性使用了左右双中括号的形式:

    [[属性]]
    //例子如下:
    //应用于函数
    [[第一个]] void[[第二个]] func[[第三个]]()[[第四个]]
    {
        cout << "属性的应用" << endl;
    }[[第五个]]
    //应用于数组
    [[第一个]] int[[第二个]] array[[第三个]][10] [[第四个]];
    //应用于变量
    [[第一个]] int[[第二个]] a [[第三个]]=5;
    //应用于类
    class[[第8个]] A{};
    
    //中括号内的内容可以是随意字符串,但如果不是预定义属性则会警告未标识属性。
    //除了属性在类中的位置要求在中间外,其他的比较随意

      在C++11标准中,只预定义了两个通用属性,分别是[[noreturn]]和[[carries_dependency]]。

      ③预定义的通用属性 ^

      C++11预定义的通用属性包括[[noreturn]]和[[carries_dependency]]两种。

      [[noreturn]]用于标识不会返回的函数,即函数在被调用后,后续代码不会再被执行,与没有返回值是有区别的,主要用于标识那些不会将控制流返回给原调用函数的函数,典型的例子有:终止应用程序语句的函数,有无限循环语句的函数,有异常抛出的函数等。通过这个属性,我们可以告知编译器某些函数不会将控制流返回给调用函数,这能帮助编译器产生更好的警告,同时做一些优化工作。

      [[carries_dependency]]跟并行情况下的编译器优化有关,主要是为了解决弱内存模型平台上使用memory_order_consume内存顺序枚举问题。以后再深入了解

    3.Unicode支持 ^

      

      ①字符集,编码和Unicode ^

      一个标准中能够表示的所有字符的集合称为字符集,ISO/Unicode所定义的字符集为Unicode。在Unicode中,每个字符占据一个码位。Unicode字符集总共定义了1114112个这样的码位,使用从0到10FFFF的十六进制数唯一地表示所有的字符。不过为了兼容ASCII等,通常情况下,我们需要一种具体的编码方式来对字符码位进行存储,比较常见基于Unicode字符集的编码方式有UTF-8,UTF-16,UTF-32。UTF-8中,英文通常使用1字节,且与ASCII兼容,而中文常用3字节进行表示。

      用于中文的常见的字符集,有GB2312和Big5。

  • GB2312字符集是作为简体中文的标准,收入了6763个汉字和682个非汉字图形字符,在编码上,是采用基于区位码的一种编码方式,采用2字节表示一个中文字符。
  • Big5字符集是作为繁体中文的标准,俗称“大五码”。共收录了13060个中文字,采用了2字节的方式表示繁体中文。
  •   ②C++11中的Unicode支持 ^

      C++11中,引入了两种新的内置数据类型来存储不同编码长度的Unicode数据:

  • char16_t:用于存储UTF-16编码的Unicode数据
  • char32_t:用于存储UTF-32编码的Unicode数据
  •   UTF-8编码的Unicode数据,C++11还是使用1字节宽度的char类型的数据来保存。C++11还定义了一些常量字符串的前缀。如:

  • u8表示为UTF-8编码
  • u表示为UTF-16编码
  • U表示为UTF-32编码
  •   对于Unicode编码字符的书写,C++11中规定了一些简明的方式,即在字符串中用“\u”加4个十六进制数编码的Unicode码位(UTF-16)来标识一个Unicode字符。如”\u4F60” 表示的是Unicode中的中文字符“你”。也可以在字符串中用“\U”后跟8个十六进制数编码的Unicode码位(UTF-32)的方式来书写Unicode字面常量。

    4.原生字符串字面量 ^

      原生字符串中的字符串“所见即所得”,不再需要如’\t’,’\n’等控制字符来调整字符串中的格式。

      C++11中,我们只需要在字符串前加入前缀,即字母R,并在引号中使用括号左右标识,就可以声明该字符串字面量为原生字符串了,如:

        cout << R"(hello
                 world)" << endl;
        //输出:hello
        //        world

      原生字符串字面量也像C的字符串字面量一样遵循连接规则,如:

        cout << R"(你
                 好)" "不  好"
            << endl;

    猜你喜欢

    转载自blog.csdn.net/qq_17044529/article/details/82520111