您当前的位置:首页 > 计算机 > 编程开发 > VC/VC++

关键字volatile、explicit

时间:09-16来源:作者:点击数:

volatile的作用

volatile是“易变的”、“不稳定”的意思。volatile是C的一个较为少用的关键字,它用来解决变量在“共享”环境下容易出现读取错误的问题。

定义为volatile的变量是说这变量可能会被意想不到地改变,即在你程序运行过程中一直会变,你希望这个值被正确的处理,每次从内存中去读这个值,而不是因编译器优化从缓存的地方读取,比如读取缓存在寄存器中的数值,从而保证volatile变量被正确的读取。

在单任务的环境中,一个函数体内部,如果在两次读取变量的值之间的语句没有对变量的值进行修改,那么编译器就会设法对可执行代码进行优化。由于访问寄存器的速度要快过RAM(从RAM中读取变量的值到寄存器),以后只要变量的值没有改变,就一直从寄存器中读取变量的值,而不对RAM进行访问。

而在多任务环境中,虽然在一个函数体内部,在两次读取变量之间没有对变量的值进行修改,但是该变量仍然有可能被其他的程序(如中断程序、另外的线程等)所修改。如果这时还是从寄存器而不是从RAM中读取,就会出现被修改了的变量值不能得到及时反应的问题。如下程序对这一现象进行了模拟。

那如何抑制编译器对读取变量的这种优化,来防止错误读取呢?volatile可以轻松胜任,将上面的程序稍作修改,将变量i前申明为volatile即可,观察如下程序:

#include <iostream>
using namespace std;

int main(int argc,char* argv[])
{
    volatile int i=10;
    int a=i;
    cout<<a<<endl;
    _asm
    {
        mov dword ptr [ebp-4],80
    }
    int b=i;
    cout<<b<<endl;
    getchar();
}

程序输出结果为:

10

80

也就是说,第二次读取变量i的值的时候,已经获得了变化之后的值。跟踪汇编代码可知,凡是申明为volatile的变量,每次都是从内存中读取变量的值,而不是在某些情况下直接从寄存器中取值。

explicit的作用

explicit

关键字在C++中用于修饰只有一个参数的构造函数,或者可以被隐式转换为单个参数的构造函数。其主要作用是防止构造函数被用于隐式类型转换,从而避免可能的错误或不符合预期的行为。

使用位置

explicit 关键字用于类的构造函数声明之前。

class MyClass {  
public:  
    explicit MyClass(int x) : value(x) {}  // explicit 关键字防止隐式转换  
    int value;  
};  
  
void func(MyClass obj) {  
    // 函数体  
}  
  
int main() {  
    MyClass obj(10);  // 正确,显式调用构造函数  
    // func(20);      // 错误,如果构造函数不是explicit的,这行代码将尝试隐式转换20为MyClass对象  
    func(MyClass(20)); // 正确,显式创建MyClass对象  
    return 0;  
}

作用

防止隐式类型转换:这是explicit最直接的作用。通过阻止构造函数用于隐式类型转换,可以避免一些意外的行为,特别是当构造函数接受基本数据类型(如int、float等)作为参数时。

提高代码清晰度:使用explicit可以明确表示构造函数不应该被用于隐式类型转换,这有助于其他开发者(或未来的你)理解代码的意图,提高代码的可读性和可维护性。

避免潜在错误:隐式类型转换有时会导致难以发现的错误,特别是在复杂或大型的项目中。通过使用explicit,可以在编译阶段就捕获到这些潜在的错误,从而避免在运行时出现更严重的问题。

符合C++的设计哲学:C++强调显式而非隐式,explicit关键字的使用符合这一设计哲学。它鼓励开发者明确表达他们的意图,而不是依赖编译器来猜测。

总之,explicit关键字是C++中一个非常有用的特性,它可以帮助我们避免由于隐式类型转换而引入的错误,提高代码的质量和可维护性。

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门
本栏推荐