zoukankan      html  css  js  c++  java
  • C++ part8

    1、volatile关键字

    在C++中,对volatile修饰的对象的访问,有编译器优化上的副作用:

    1. 不允许被编译器优化,提供特殊地址的稳定访问(只从内存中读取)。
    2. 有序性,编译器进行优化时,不能把对volatile对象前面的其他volatile语句放到他后面,反之也不行。也就是说volatile变量间的操作,是不会被编译器交换顺序的。

    注意:
    在多线程数据同步时,很多人会选择volatile来修饰全局的变量,使得线程同步。其实是不对的。由有序性可得,编译器可能对语句的位置进行交换,使得程序错误。

    volatile bool flag = false;
    
    //线程1
    while(flag == false){
    done();
    }
    
    
    //线程2
    update();	//语句1
    flag = true;	//语句2
    

    上述代码中,编译时语句2可能和语句1调换位置,在多线程中,这可能会发生错误。

    2、内联函数和宏定义

    宏定义由预处理器实现,做一些简单的字符替换。
    内联函数(inline)使用时,编译器将使用函数代码替换函数调用,这样就节省了函数调用的时间,但是增加了内存空间。

    区别:

    1. 宏定义不能进行数据类型的检查,内联函数可以
    2. 宏定义展开发生在预编译阶段,内联函数展开发生在编译阶段
    3. inline作为类的成员函数可以调用类的对象,宏定义因为是文本替换,不可以

    不适合使用内联函数的情况:

    1. 当inline内出现for,while时,函数的运行时间就比函数调用时间多出很多,那么使用inline的效率就很低,相反需要付出内存空间。
    2. inline不能使用递归。
    3. 函数体比较长,会消耗大量内存空间。
    4. 构造函数和析构函数不适合作为内联函数使用,因为编译阶段编译器会往构造和析构函数中额外加很多代码,比如申请/释放内存,初始化成员对象等等,可能代码并不精简。

    3、Lambda

    lambda表达式在其所在的位置上定义了一个匿名函数对象。
    lambda表达式的形式:

    [捕获值列表] (函数参数) mutable / exception -> 返回值类型 {函数体}

    捕获值列表:分为值捕获,引用捕获。捕获的参数是我们能直接在函数体中使用的参数。和一般的函数不同的是,值捕获的值是在lambda创建时捕获的,也就是说在lambda创建后再改变值不会改变lambda内的捕获的值。

    //example1
    int a = 1;
    auto fun = [a](){ return a; };
    a = 11;
    std::cout << fun();	//1
    
    //example2
    int a = 1;
    auto fun = [&a](){ return a; };
    a = 11;
    std::cout << fun();	//11
    

    函数参数:表示匿名函数的参数。
    返回值类型:return的类型,void可以忽略。
    函数体:函数的主体。

    参考资料:

    谈谈 C/C++ 中的 volatile
    C++之Lambda表达式

  • 相关阅读:
    VS2010 error LNK2019: 无法解析的外部符号
    strspn()函数的使用方法
    直接插入排序
    opecv 常用的函数
    matlab中 fprintf 和disp的用法
    面试经历
    挚爱 泰戈尔
    见与不见
    无题
    Cannot create PoolableConnectionFactory (Could not create connection to database server.
  • 原文地址:https://www.cnblogs.com/KirinSB/p/12833377.html
Copyright © 2011-2022 走看看