`
jgsj
  • 浏览: 951713 次
文章分类
社区版块
存档分类
最新评论

C++关键字详解

 
阅读更多

转自:http://cyinger-smiling.blogbus.com/logs/31041587.html

c++关键字详解(volatile, mutable, explicit, dynamic_ cast<T>(expression))

1 volatile
有些变量是用volatile关键字声明的。当两个线程都要用到某一个变量且该变量的值会被改变时,应该用volatile声明,该关键字的作用是防止优化编译器把变量从内存装入CPU寄存器中。如果变量被装入寄存器,那么两个线程有可能一个使用内存中的变量,一个使用寄存器中的变量,这会造成程序的错误执行。 volatile的意思是让编译器每次操作该变量时一定要从内存中真正取出,而不是使用已经存在寄存器中的值,如下:
volatile BOOL bStop = FALSE;

在一个线程中:
while( !bStop )
{
...
}
bStop = FALSE;
return;

在另外一个线程中,要终止上面的线程循环:
bStop = TRUE;
while( bStop ); //
等待上面的线程终止,如果bStop不使用volatile申明,那么这个循环将是一个死循环,因为bStop已经读取到了寄存器中,寄存器中bStop的值永远不会变成FALSE,加上volatile,程序在执行时,每次均从内存中读出bStop的值,就不会死循环了。
这个关键字是用来设定某个对象的存储位置在内存中,而不是寄存器中。因为一般的对象编译器可能会将其的拷贝放在寄存器中用以加快指令的执行速度,例如下段代码中:
...
int nMyCounter = 0;
for(; nMyCounter<100;nMyCounter++)
{
...
}
...
在此段代码中,nMyCounter的拷贝可能存放到某个寄存器中(循环中,对nMyCounter的测试及操作总是对此寄存器中的值进行),但是另外有又段代码执行了这样的操作:nMyCounter -= 1;这个操作中,对nMyCounter的改变是对内存中的nMyCounter进行操作,于是出现了这样一个现象:nMyCounter的改变不是同步的


2 extern
2A
c++中,还可用来指定使用另一语言进行链接,这时需要与特定的转换符一起使用。目前microsoft c/c++仅支持”c”转换标记,来支持c编译器链接。使用这种情况有两种形式:
u extern “c”
声明语句
u extern “c” {
声明语句块 }

2B extern LPDIRECTDRAW4 lpdd; 声明lpdd,但是不分配内存,只说明他是你可以用的变量,在此程序之外其他的程序中已经声名了他。 其实他就是防止名字冲突~ 被其修饰的变量(外部变量)是静态分配空间的,即程序开始时分配,结束时释放
如果一个头文件被 #include 到一个以上的源文件 里,这个头文件中所有的定义就会出现在每一个有关的源码文件里。这会使它们里的符号被定义一次以上,从而出现连接错误。
解决办法就是不要在头文件里定义变量。你只需要在头文件里声明它们然后在适当的源码文件(应该 #include 那个头文件的那个)里定义它们一次。extern告诉编译器其所声明的符号的存在,并不会使编译器分配贮存空间。当做一个声明而不是做定义的时候,在声明前放一个关键字“extern”
extern
关键字的作用是声明变量和函数为外部链接,即该变量或函数名在其它文件中可见。用其声明的变量或函数应该在别的文件或同一文件的其它地方定义。
例如语句:extern int a;
仅仅是一个变量的声明,其并不是在定义变量a,并未为a分配内存空间。变量a在所有模块中作为一种全局变量只能被定义一次,否则会出现连接错误。
通常,在模块的头文件中对本模块提供给其它模块引用的函数和全局变量以关键字extern声明。例如,如果模块B欲引用该模块A中定义的全局变量和函数时只需包含模块A的头文件即可。这样,模块B中调用模块A中的函数时,在编译阶段,模块B虽然找不到该函数,但是并不会报错;它会在连接阶段中从模块A编译生成的目标代码中找到此函数

3 static
静态变量作用范围在一个文件内,程序开始时分配空间,结束时释放空间,默认初始化为0,使用时可改变其值。
静态变量或静态函数,即只有本文件内的代码才可访问它,它的名字(变量名或函数名)在其它文件中不可见。
在函数体内生成的静态变量它的值也只能维持
int max_so_far( int curr )//
求至今(本次调用)为止最大值
{
static int biggest; //
该变量保持着每次调用时的最新值,它的有效期等于整个程序的有效期
if( curr > biggest )
biggest = curr;
return biggest;
}
c++类的成员变量被声明为static(称为静态成员变量),意味着它为该类的所有实例所共享,也就是说当某个类的实例修改了该静态成员变量,其修改值为该类的其它所有实例所见;而类的静态成员函数也只能访问静态成员(变量或函数)。
类的静态成员变量必须在声明它的文件范围内进行初始化才能使用,private类型的也不例外。如,
float savingsaccount::currentrate = 0.00154;
(注:currentrate是类savingsaccount的静态成员变量)

4 register
register声明的变量称着寄存器变量,在可能的情况下会直接存放在机器的寄存器中;但对32位编译器不起作用,当global optimizations(全局优化)开的时候,它会做出选择是否放在自己的寄存器中;不过其它与register关键字有关的其它符号都对32位编译器有效。

5 auto
它是存储类型标识符,表明变量(自动)具有本地范围,块范围的变量声明(如for循环体内的变量声明)默认为auto存储类型。

6 const
const
所修饰的对象或变量不能被改变,修饰函数时,该函数不能改变在该函数外面声明的变量也不能调用任何非const函数。在函数的声明与定义时都要加上const,放在函数参数列表的最后一个括号后。
c++
中,用const声明一个变量,意味着该变量就是一个带类型的常量,可以代替#define,且比#define多一个类型信息,且它执行内链接,可放在头文件中声明;但在c中,其声明则必须放在源文件(即.c文件)中,在cconst声明一个变量,除了不能改变其值外,它仍是一具变量,如
const int maxarray = 255;
char store_char[maxarray]; //c++
中合法,c中不合法

1.如果const位于星号左侧,const用来修饰指针所指向的变量,
即指针指向的为不可变的.
2.
如果const位于星号右侧,const就是修饰指针本身,即指针本身是
不可变的.


7 mutable
关键字的用法
关键字mutableC++中一个不常用的关键字,他只能用于类的非静态和非常量数据成员
我们知道一个对象的状态由该对象的非静态数据成员决定,所以随着数据成员的改变,
对像的状态也会随之发生变化!
如果一个类的成员函数被声明为const类型,表示该函数不会改变对象的状态,也就是
该函数不会修改类的非静态数据成员.但是有些时候需要在该类函数中对类的数据成员
进行赋值.这个时候就需要用到mutable关键字了

mutable关键字提示编译器该变量可以被类的const函数修改

8 explicit
explicit
关键字用于取消构造函数的隐式转换,对有多个参数的构造函数使用explicit是个语法错误。


9 C++
同时提供了四种新的强制转型形式(通常称为新风格的或 C++ 风格的强制转型):
const_cast<T>(expression)
dynamic_cast<T>(expression)
reinterpret_cast<T>(expression)
static_cast<T>(expression)
每一种适用于特定的目的:

  ·const_cast 一般用于强制消除对象的常量性。它是唯一能做到这一点的 C++ 风格的强制转型。

  ·dynamic_cast 主要用于执行安全的向下转型(safe downcasting,也就是说,要确定一个对象是否是一个继承体系中的一个特定类型。它是唯一不能用旧风格语法执行的强制转型。也是唯一可能有重大运行时代价的强制转型。(过一会儿我再提供细节。)

  ·reinterpret_cast 是特意用于底层的强制转型,导致实现依赖(implementation-dependent)(就是说,不可移植)的结果,例如,将一个指针转型为一个整数。这样的强制转型在底层代码以外应该极为罕见。在本书中我只用了一次,而且还仅仅是在讨论你应该如何为裸内存(raw memory)写一个调谐分配者(debugging allocator)的时候。

  ·static_cast 可以被用于强制隐型转换(例如,non-const 对象转型为 const 对象(就像 Item 3 中的),int 转型为 double,等等)。它还可以用于很多这样的转换的反向转换(例如,void* 指针转型为有类型指针,基类指针转型为派生类指针),但是它不能将一个 const 对象转型为 non-const 对象。(只有 const_cast 能做到。)

A:转换的含义是通过改变一个变量的类型为别的类型从而改变该变量的表示方式。为了类型转换一个简单对象为另一个对象你会使用传统的类型转换操作符。比如,为了转换一个类型为double的浮点数的指针到整型:
代码:
int i;
double d;

i = (int) d;
或者:

i = int (d);

对于具有标准定义转换的简单类型而言工作的很好。然而,这样的转换符也能不分皂白的应用于类(class)和类的指针。ANSI-C++标准定义了四个新的转换符:'reinterpret_cast', 'static_cast', 'dynamic_cast' 'const_cast',目的在于控制类(class)之间的类型转换。
代码:
reinterpret_cast<new_type>(expression)
dynamic_cast<new_type>(expression)
static_cast<new_type>(expression)
const_cast<new_type>(expression)

const_cast:允许添加或删除表达式类型的constvolatile关键字.
static_cast:
用于将一个继承层次结构中的基类类型的指针或引用向下转换为一个派生类的指针或引用。
dynamic_cast:
仅适用于多态类型的向下转换,被转换的类型必须是一个指向含有虚函数的类类型的指针。
reinterpret_cast:
从位的角度来看待一个对象,从而允许将一个东西看成是完全不同的另一个东西,最强的一种转换。

1 reinterpret_cast

'reinterpret_cast'转换一个指针为其它类型的指针。它也允许从一个指针转换为整数类型。反之亦然。(译注:是指针具体的地址值作为整数值?)
这个操作符能够在非相关的类型之间转换。操作结果只是简单的从一个指针到别的指针的值的二进制拷贝。在类型之间指向的内容不做任何类型的检查和转换。

如果情况是从一个指针到整型的拷贝,内容的解释是系统相关的,所以任何的实现都不是方便的。一个转换到足够大的整型能够包含它的指针是能够转换回有效的指针的。

代码:
class A {};
class B {};

A * a = new A;
B * b = reinterpret_cast<B *>(a);
'reinterpret_cast'
就像传统的类型转换一样对待所有指针的类型转换。

2 static_cast

'static_cast'允许执行任意的隐式转换和相反转换动作。(即使它是不允许隐式的)

应用到类的指针上,意思是说它允许子类类型的指针转换为父类类型的指针(这是一个有效的隐式转换),同时,也能够执行相作:转换父类为它的子类。

在这最后例子里,被转换的父类没有被检查是否与目的类型相一致。
代码:
class Base {};
class Derived : public Base {};

Base *a = new Base;
Derived *b = static_cast<Derived *>(a);
'static_cast'
除了操作类型指针,也能用于执行类型定义的显式的转换,以及基础类型之间的标准转换:

代码:
double d = 3.14159265;
int i = static_cast<int>(d);

3 dynamic_cast

'dynamic_cast'只用于对象的指针和引用。当用于多态类型时,它允许任意的隐式类型转换以及相反过程。不过,与static_cast不同,在后一种情况里(注:即隐式转换的相反过程),dynamic_cast会检查操作是否有效。也就是说,它会检查转换是否会返回一个被请求的有效的完整对象。
检测在运行时进行。如果被转换的指针不是一个被请求的有效完整的对象指针,返回值为NULL.
代码:
class Base { virtual dummy() {} };
class Derived : public Base {};

Base* b1 = new Derived;
Base* b2 = new Base;

Derived* d1 = dynamic_cast<Derived *>(b1); // succeeds
Derived* d2 = dynamic_cast<Derived *>(b2); // fails: returns 'NULL'

如果一个引用类型执行了类型转换并且这个转换是不可能的,一个bad_cast的异常类型被抛出:
代码:
class Base { virtual dummy() {} };
class Derived : public Base { };

Base* b1 = new Derived;
Base* b2 = new Base;

Derived d1 = dynamic_cast<Derived &*>(b1); // succeeds
Derived d2 = dynamic_cast<Derived &*>(b2); // fails: exception thrown

4 const_cast

这个转换类型操纵传递对象的const属性,或者是设置或者是移除:
代码:
class C {};

const C *a = new C;

C *b = const_cast<C *>(a);
其它三种操作符是不能修改一个对象的常量性的。
注意:'const_cast'也能改变一个类型的volatile qualifier

--------------------------------------------------------------------

C++4种类型转换

一、C 风格(C-style)强制转型如下:

(T) expression // cast expression to be of type T
函数风格(Function-style)强制转型使用这样的语法:
T(expression) // cast expression to be of type T
这两种形式之间没有本质上的不同,它纯粹就是一个把括号放在哪的问题。我把这两种形式称为旧风格(old-style)的强制转型。

二、 C++的四种强制转型形式:

  C++ 同时提供了四种新的强制转型形式(通常称为新风格的或 C++ 风格的强制转型):
  const_cast(expression)
  dynamic_cast(expression)
  reinterpret_cast(expression)
  static_cast(expression)

  每一种适用于特定的目的:

  ·dynamic_cast 主要用于执行安全的向下转型(safe downcasting,也就是说,要确定一个对象是否是一个继承体系中的一个特定类型。它是唯一不能用旧风格语法执行的强制转型,也是唯一可能有重大运行时代价的强制转型。

·static_cast
可以被用于强制隐型转换(例如,non-const 对象转型为 const 对象,int 转型为 double,等等),它还可以用于很多这样的转换的反向转换(例如,void* 指针转型为有类型指针,基类指针转型为派生类指针),但是它不能将一个 const 对象转型为 non-const 对象(只有 const_cast 能做到),它最接近于C-style的转换。

  ·const_cast 一般用于强制消除对象的常量性。它是唯一能做到这一点的 C++ 风格的强制转型。

  ·reinterpret_cast 是特意用于底层的强制转型,导致实现依赖(implementation-dependent)(就是说,不可移植)的结果,例如,将一个指针转型为一个整数。这样的强制转型在底层代码以外应该极为罕见。
  
  旧风格的强制转型依然合法,但是新的形式更可取。首先,在代码中它们更容易识别(无论是人还是像 grep 这样的工具都是如此),这样就简化了在代码中寻找类型系统被破坏的地方的过程。第二,更精确地指定每一个强制转型的目的,使得编译器诊断使用错误成为可能。例如,如果你试图使用一个 const_cast 以外的新风格强制转型来消除常量性,你的代码将无法编译。

==
== dynamic_cast .vs. static_cast
==

class B { ... };
class D : public B { ... };

void f(B* pb)
{
D* pd1 = dynamic_cast<D*>(pb);
D* pd2 = static_cast<D*>(pb);
}

If pb really points to an object of type D, then pd1 and pd2 will get the same value. They will also get the same value if pb == 0.

If pb points to an object of type B and not to the complete D class, then dynamic_cast will know enough to return zero. However, static_cast relies on the programmer’s assertion that pb points to an object of type D and simply returns a pointer to that supposed D object.

dynamic_cast可用于继承体系中的向下转型,即将基类指针转换为派生类指针,比static_cast更严格更安全。dynamic_cast在执行效率上比static_cast要差一些,static_cast在更宽上范围内可以完成映射,这种不加限制的映射伴随着不安全性.static_cast覆盖的变换类型除类层次的静态导航以外,还包括无映射变换,窄化变换(这种变换会导致对象切片,丢失信息),VOID*的强制变换,隐式类型变换等...


==
== static_cast .vs. reinterpret_cast
==

reinterpret_cast是为了映射到一个完全不同类型的意思,这个关键词在我们需要把类型映射回原有类型时用到它.我们映射到的类型仅仅是为了故弄玄虚和其他目的,这是所有映射中最危险的.(这句话是C++编程思想中的原话)

static_cast reinterpret_cast 操作符修改了操作数类型. 它们不是互逆的; static_cast 在编译时使用类型信息执行转换, 在转换执行必要的检测(诸如指针越界计算, 类型检查). 其操作数相对是安全的. 另一方面, reinterpret_cast 仅仅是重新解释了给出的对象的比特模型而没有进行二进制转换, 例子如下:

int n=9; double d=static_cast < double > (n);

上面的例子中, 我们将一个变量从 int 转换到 double. 这些类型的二进制表达式是不同的. 要将整数 9 转换到 双精度整数 9, static_cast 需要正确地为双精度整数 d 补足比特位. 其结果为 9.0. reinterpret_cast 的行为却不同:

int n=9;
double d=reinterpret_cast<double & > (n);

这次, 结果有所不同. 在进行计算以后, d 包含无用值. 这是因为 reinterpret_cast 仅仅是复制 n 的比特位到 d, 没有进行必要的分析.

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

转自:http://hi.baidu.com/bellgrade/blog/item/9bb7d5ec17c7474578f0559f.html

c++ 关键字--volatile

①一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。

关于优化:在单任务下,在一个函数体内,如果两次读取变量间语句没有对变量的值进行修改,那么编译器就会进行优化。由于寄存器速度快于RAM,所以一般会减少存取外部RAM。

②该变量的适用情况:

1) 并行设备的硬件寄存器(如:状态寄存器)

2) 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)

3) 多线程应用中被几个任务共享的变量

③实例

Example 1:

#1 int i=10;

#2 int a=i;

#3 cout<<a<<endl;

#4 _asm //通过内存地址修改变量i的值为80

#5 {

#6 mov dword ptr[ebp-4],80

#7 }

#8 int b=i;

#9 cout<<b<<endl;

在VC下生存release版(注:Debug版不对代码进行优化)结果打印 10 10

如果将i声明为volatile变量就能正确了。跟踪汇编代码可发现volatile是从内存中而不是寄存器中读取值的。

Example 2:

int s;

for(int i=0;i<10;i++)

for(int j=0;j<10;j++)

for(int k=0;k<10;k++)

s=5;

假设程序初衷是“拖时间”,那么将达不到要求,编译器会将这三重循环优化为一条语句s=5;

如想实现可将变量s声明为 volatile。

Question:

1)一个参数既可以是const还可以是volatile吗?解释为什么。

2) 一个指针可以是volatile 吗?解释为什么。

3) 下面的函数有什么错误:

int square(volatile int *ptr)

{

return *ptr * *ptr;

}

Answer:

1)是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。

2); 是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。

3) 这段代码有点变态。这段代码的目的是用来返指针*ptr指向值的平方,但是,由于*ptr指向一个volatile型参数,编译器将产生类似下面的代码:

int square(volatile int *ptr)

{

int a,b;

a = *ptr;

b = *ptr;

return a * b;

}

由于*ptr的值可能被意想不到地该变,因此a和b可能是不同的。结果,这段代码可能返不是你所期望的平方值!正确的代码如下:

long square(volatile int *ptr)

{

int a;

a = *ptr;

return a * a;

}

/////////////////////////////////////////////////////////////////////////////////////////////////

转自:http://www.cnblogs.com/lidp/archive/2009/05/06/1698010.html

c++ 全面掌握const、volatile和mutable关键字

C++ 程式设计过程中 ,const 的使用可以频度是非常高的 . 它在保证程式安全方面起到了不可估量的作用 .用一句话来表达最确切不过了:"小兵立大功" .有了 const, 那么 mutable 当然缺不了 .然作为 const 的同胞兄弟 ,volatile 却在很多人的视野中消失 . 其实
volatile 担负的责任有何尝小呢 ?自然 , 它们的用法多样而灵巧 , 以至新手迷惑久久 , 下面就来系统的探讨总结一下吧:
一 . 一般应用
1.const 修饰各种变量的用法 .
a. 取代 define
#define D_INT 100
#define D_LONG 100.29
………
const int D_INT = 100;
const D_INT = 100; // 如果定义的 int 类型 , 可省略 int.
const long D_LONG = 100.29;
………
const int& a = 100;
const 替代 define 虽然增加分配空间 , 可它却保证了类型安全 .
在 C 标准中 ,const 定义的数据相当于全局的 , 而 C++ 中视声明的位置而定 .
b. 修饰指针相关的变量
以三组简单的定义示意:
Group1:
int a = 0;
const int* b = &a;------------ [1]
int const *b = &a;------------ [2]
const int* const b = &a;---- [4]

Group2:
const char *p = "const";--------------[1]
char const *p = "const";--------------[2]
char* const p = "const";--------------[3]
const char * const p = "const";----[4]

Group3:
int a=0;
const int &b = a;---------------[1]
int const &b = a;---------------[2]
int & const b = a;--------------[3] //---> 修饰引用时 ,const 被忽略
const int & const b = a;-----[4]
总结:
1. 如果 const 位于星号左侧 , 则 const 用来修饰指针所指向的变量 ,即指针指向的为不可变的 .
2. 如果 const 位于星号右侧 ,const 就是修饰指针本身 , 即指针本身是不可变的 .
因此 ,[1] 和 [2] 的情况相同 , 指针所指向内容不可变 (const 放在变量声明符的位置无关 ),这种情况下不允许对内容进行更改 , 如不能 *a = 3 ;
3.[3] 中指针本身是不可变的,而指针所指向的内容是可变的 , 这种情况下不能对指针本身进行更改操作 , 如 a++ 是错误的
4.[4] 中指针本身和指向的内容均为常量 .( 引用特殊:引用在使用增加
遇义时 , 增加它代表的变量 . 所以 qualifiers on reference are ignoredv.
延伸点 :
注意示例 :
1.const int& reference = 1000;
2.char* p = "const"
char*& q ;

2.const 在函数环境下的各种应用
常用法示例如下:
const A& _Fun(const A& _in); // 修饰引用型传入参数
// A _Fun(const A& _in);
//A& _Fun(const A& _in);
// 上面的两种 , 在函数内部有特殊的步骤 , 这里不详提了… ..

const A* _Fun( const A* _in); // 修饰指针型传入参数
void _Fun( ) const; // 修饰 class 成员函数
const A& _Fun(A& _in ); // 修饰返回值
const A & operator(const A& _in); // 同时修饰传入参数和返回值
a. 修饰参数
如 void _Fun(const A* _in) 或 void _Fun(const A& _in);
它们被修饰后 , 在函数执行期间行为特性同于上面的讲解 ,
注意:这不会改变原来数据的是否是 const 的属性 .
b. 修饰函数返回值
const A& _Fun( )
const A* _Fun( );
注意:由于生命期不同步的问题 , 不可将局部的变量的指针或引用返回
(static 除外 ).
另外 , 传出来的视情况 , 代表不同的意思…对于 A& 返回类型 , 你若将之赋与其它变量 , 那么它实际执行的是将返回的变量( 或引用 ) 代表的数据赋出 .. 而你若将其它值赋予之 , 那么被赋予的是变量或引用代表的数据 . 而 const A& 一般是防止之做为左值被赋值 .这个地方还有很多的细节问题 ( 譬如在连续赋值、返回的临时对象的处理、重载的 const 和非 cosnt 运算符等等 ), 读者自己在实践中需要多多总结 .
二、难点
3. 修饰类成员函数的 const.
形如 :void _Fun() const { };
你需要知道的几点规则:
a.const 对象只能访问 const 成员函数 , 而非 const 对象可以访问任意的成员函数 , 包括 const 成员函数 .
b.const 对象的成员是不可修改的 , 然而 const 对象通过指针维护的对象却是可以修改的 .
c.const 成员函数不可以修改对象的数据 , 不管对象是否具有 const 性质 . 它在编译时 , 以是否修改成员数据为依据 , 进行检查 .
e. 然而加上 mutable 修饰符的数据成员 , 对于任何情况下通过任何手段都可修改 , 自然此时的 const 成员函数是可以修改它的…
4. 谈谈 volatile 和"完全 const 对象"
一个有 volatile 修饰的类只允许访问其接口的一个子集,这个子集由类的实现者来控制 . 用户只有用 const_cast 才可以访问这个类型的全部接口 . 而且 ,象 const 一样,类的 volatile 属性会传递给它的成员 . 想象 const 修饰的对象 , 它的成员变量是不可修改的 , 而它通过指针维护的对象或原生变量是可修改 . 那么我们想 : 如果对象维护一个 char* , 则它相当于 char*const chrptr ; 而不是 const char* cosnt chrptr; 对于类中的指针你需要这样修饰以防止它或它维护的资源: cosnt x* xptr; 而不是 x*const xptr;因为 cosnt 修饰的对象它默认 的行为是延续变量: x* cosnt xptr;更重要的 ,volatile 修饰的数据 , 编译器不可对其进行执行期寄存于寄存器的优化 .
这种特性 , 是为了多线程同步的需要 . 有兴趣者看参看 Andrei 的 GP 系列文章 .
5. 谈谈 const_cast 转换运算符
这个关键字最基础的用法是:去掉数据的 const 性质 .值得注意的是:它只对指针、引用和其它的具有指向性质的类型 .
参考:
1. 《 Effective C++ 》关于 const 两种语义的论述
2.Andrei Alexandrescu 《 volatile ——编写多线程程序的好帮手》

分享到:
评论

相关推荐

    C++关键字详解[参照].pdf

    C++关键字详解[参照].pdf

    c++关键字详解

    C++关键字

    C++中关键字的探讨

    C++的有些关键字的详解,收集一下很有帮助的

    C++const关键字详解

    C++中const关键字详解

    C++中const关键字详解

    C++中const关键字详解

    c++中const关键字使用详解

    一 const基础;二 const的初始化;三 作为参数和返回值的const修饰符;四 类成员函数中const的使用;五 使用const的一些建议。

    C++ 中try finally关键字详解

    try-finally语句是Microsoft对C和C++语言的扩展,它能使32位的目标程序在异常出现时,有效保证一些资源能够被及时清除,这些资源的清除任务可以包括例如内存的释放,文件的关闭,文件句柄的释放等等。try-finally...

    C/C++ 中extern关键字详解

    主要介绍了C/C++ 中extern关键字详解的相关资料,需要的朋友可以参考下

    c++中关键字const的用法详解

    本文档详细介绍了C++中关键字const的用法,并给出了具体的示例来帮助读者理解

    C++ override关键字使用详解

    主要介绍了C++ override关键字使用详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    const关键字详解

    关于C++中的const关键字的用法非常灵活,而使用const将大大改善程序的健壮性

    Java中的final关键字详解及实例

    这是final的主要用途之一,和C/C++的const,即该成员被修饰为常量,意味着不可修改。   上面的代码对age进行初始化后就不可再次赋值,否则编译时会报类似上图的错误。 如果修饰的是引用类型的变量,那么初始化...

    C++中const关键字用法详解及实例和源码下载

    最近在学习C++基础部分,看了两天书,已经看过了一遍,半知半解,回过头来重新看第二遍,深入了解一下C++的基础知识。现在读到了const关键字的用法,书上面讲解的时候并没有给出完整的实例,只是理论的讲解了一些...

    C++ 语言命令详解(第二版) pdf

    C++ 语言命令详解 全书由两大部分及四个附录和一个词汇表构成,第一部分介绍 C++的基本概念以及C++程序设计方法,这部分从C++最基本的概念讲 起,覆盖最新C++标准中的所有概念并重点介绍类及其有关的函数和 运算符.第二...

    C++语言详解.pdf

    C++不错的教程 C++的基本概念和C++程序设计方法 先从C++的最基本的概念讲起,介绍类及其有关的函数和运算符.数据类型.运算符,类型转换,关键字,预处理指令及库函数和类库.

    C++ operator关键字(重载操作符)的用法详解

    下面小编就为大家带来一篇C++ operator关键字(重载操作符)的用法详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    C++面试基础之static关键字详解

    static是 c++ 的关键字,顾名思义是表示静态的含义。它在 c++ 中既可以修饰变量也可以修饰函数。那当我们使用 static 时,编译器究竟做了哪些事情呢? 早先面试中被问到 static 关键字,感觉既熟悉又陌生。熟悉是都...

    C/C++中extern关键字详解

    则告诉编译器在编译fun这个函数名时按着C的规则去翻译相应的函数名而不是C++的,C++的规则在翻译这个函数名时会把fun这个名字变得面目全非,可能是fun@aBc_int_int#%$也可能是别的,这要看编译器的脾气了(不同的...

Global site tag (gtag.js) - Google Analytics