auto/register/volatile/static/const/mutable

原创 2010年05月31日 20:35:00

1)          auto

auto变量就是局部变量,一般不用加auto。自动的意思是自动作用域,自动离开作用域。

 

2)          register

register变量是提示编译器尽量放在寄存器中保存,以增加

速度。

l       只能定义局部的register变量,或者作为函数参数,没有全局或静态的。

l       C语言中,是不能对register变量取地址的,因为它没有虚地址,在寄存器里。而C++中,它是可以取址的,这时,C++编译器不会把它放到寄存器里。

l       一般不建议使用register,相信编译器能够做的更好。

 

3)          volatile

l       volatile变量

告诉编译器,别对这个变量做任何优化,因为它随时都会改变。

 

比如,多线程中,共同访问一个变量,如果编译器对其优化(放在寄存器中是优化的一种),第二次读时可能直接读寄存器中的值,而另外一个线程(或中断)改了变量,结果读出来的值是旧的。

 

它和const/register是类相反的,const是告诉编译器这是不可改变的,可以优化。而register直接告诉编译器将变量存入寄存器中。

 

用法

volatile int a;

 

l       volatile函数

int i = 0;

void Func1 volatile()

{

if ( i == 10 )

{

//操作
}

}

这可以告诉编译器,别对函数里的变量访问进行优化,因为这些变量有可能被多线程或者中断服务程序改变。

 

4)          static

l       函数里static变量只能在本函数里可见

l       全局的static变量只能在本文件中可见,当然,如果是头文件,可以include进去,然后也是可见的。

l       它比全局变量好的原因是,不容易被错误的改变,因为它限制了变量的可见性(见上)

l       任何时候用非conststatic变量时都需要注意线程安全问题

l       内部类型的static默认初始化为0,自定义类static对象默认调用默认构造函数初始化

l       所有全局的变量都是存储在静态存储区,和static唯一不同的是它是内部链接的

关于链接方式,请参考

http://blog.csdn.net/yeming81/archive/2010/05/31/5637704.aspx

 

l       全局或静态对象的构造函数发生在进入main()之前

l       静态成员的初始化

conststatic成员的初始化只能在类外初始化;

conststatic成员只能在构造函数初始化列表初始化;

const static成员初始化可以在声明时或类外初始化;

 

class A

{

public:

    A():e(1.7f), d(1.6f) //error,static属于静态区,必须在构造

函数前初始化

    {

        printf("%f/n",a);

    }

private:

    static int a;

    static const int b = 10;

    static const float c;

    static const float d;

    const float e;

    const float f;

 

    static const int intArray[];

};

 

int A::a = 1;

const float A::c = 2.1f;

// static const float A::c = 3.1f;// error

const int A::intArray[] = {1, 3, 5};

const float A::f = 1.2f; //error, only static

 

l       局部类不能含有static成员

l       static成员函数不能是virtual

因为,虚函数是需要对象来判断类型,从而获得函数的地址(VPTR是存在对象中的)。静态的成员函数是没有this指针的。

virtual void Func(this, int a)

{

               

}

 

p->Func(1); //利用p (this)指针找到VPTR,然后得到真正函数的地址。

 

l       static变量与对象大小

class B

{

public:

    B(){}

    const static long a = 10; //常量

    const static long b = 10;

    const static long c = 10;

    static long d; //静态区

    const long e; //只有这个变量占空间

};

 

sizeof (B) = 4;

 

l       static函数的好处

1.       限制全局函数在类里

2.       static函数不能访问成员变量,所以无需带this指针参数,提高效率

 

5)          const

l       C中,const是只读的变量,不是常量;C++中它是常量。区别用例子描述如下:

const int MAX = 10;

char buffer[MAX]; //C中它是不合法的,

                 可以用enum define替代;

                                    //C++中它是合法的。

l       Cconst变量分配在全局静态区;C++中则在常量区,编译过程中值就定了。

l       C++编译器并不为const变量创建存储空间,而是保存在符号表里。如果用extern介入外部链接或者取const变量的地址,编译器必须要分配空间。

1) 普通const 变量

const int i = 10;

const int j = i+20; //常量折叠,即编译期间将i代入

int* p = &i; //取址导致内存分配

char buffer[i]; //尽管内存分配,i还是进入了符号表

2) const 数组

const int intArray [] = {1, 3, 5, 7};

char buffer[intArray[1]]; //编译错误

由于数组过于复杂,编译器不把它放入符号表,而是分配内存区保存。编译期间不会知道具体值。

l       const指针

²      指向的内容是const

以下两者写法皆可:

const int* a;

int const* a;

²      指针本身是const

int* const a;

²      两者都是const

以下两种写法皆可:

int const* const a;

const int* const a;

 

l       const 字符串陷阱

char* p = “hello”; //这时,”hello”是常量,p指针是一个指向常量的指针

所以,严格的写法应该是 const char* p = “hello”

 

如果,p[0] = ‘a’;则程序运行崩溃,因为试图去更改常量区,行为是未定义的。

 

如果想要改变一个数组,需要这样定义:

char p[] = “hello”; //注意 char [] p = “hello”是错误的!

“hello”将保存在全局静态区,而不是常量区,p指向首地址。

 

l       const参数与返回值

²      按值传递的const参数

void Func( const int i )

{

i = 10;  //目的就是防止在程序里改变临时变量

        i,对于用户而言是没//有影响的

}

所以,按值传递的const可以这样写,这样用户接口更简单。

void Func( int i )

{

const int& j = i;
}

²      按值返回的const – 防止返回值被赋值

按值返回内置类型

int Func1() { return 29; }

Func1() = 20; //编译器就阻止了这个操作,因为返回的是一个值(字面值),而不是变量。

const int Func2() { return 29; } 所以,内置类型const返回值没有必要

 

按值返回自定义类型(structclass)

class A

{

public:

void modify(){ a = 10; };

 

private:

int a;
};

                              

                               A Func1() { return A(); }

                               Func1() = A(); //合法,产生一个临时的非

                             const A对象

                               Func1().modify(); //合法,非const A对象

                                可以更改数据

 

                               const A Func2() { return A(); }

                               Func2() = A(); //不合法

                               Func2().modify(); 不合法

 

                               void Func3( A& a) {}

                               Func3( Func2() ); //不合法,因为不能

                            从const变成一个非const的引用

 

l       类里的const

²      const数据成员

class A

{

public:

A(): i (10) //必须在这初始化因为这是没有调用构 造之前唯一可行的地方

{

i = 10; //错误,不能二次初始化const

       第一次也不能在这里
}

 

private:

const int i = 10; //不能在这里初始化

static const int j  = 11; //这是合法的,且只能在这里初始化,因为:

//类里的static表示类中只有一份,在类中任何//构造函数之前就必须存在,这是编译期间常

//量,保存在符号表里

}

 

²      const函数成员

类的const对象只能调用const函数;

在函数的声明和定义都必须注明是const的!!!

例子如下:

int A::Func() const {};

在函数内部不能改变变量值。

 

²      const函数成员与mutable

如果在const函数里想改变某个变量,可将变量声明为mutable

mutable int i;

这种方法是用来替换老的野蛮法:

(A*)this ->i++; //将当前const指针转成非const指针,然后更改。

       注意:这时候,const称为是按逻辑const

         通常的const是按位const

 

l       const 对象对性能的提升

一个const能够放进ROM只读存取器,系统访问ROM是比RAM快的。

能放进ROM的条件必须满足:

²      按位const

也就是类里不能存在const方法访问mutable变量,允许有非const方法。

²      classstruct不能有用户自定义的构造函数或析构函数,也不能包含有用户自定义的构造函数或析构函数的对象。

²      不能有基类

因为需要初始化基类。

 

C语言系列之 函数指针与 const

清华大学尹成老师、微软全球最具价值专家,带你步入 C 语言的殿堂,讲课生动风趣、深入浅出,全套视频内容充实,整个教程以 C 语言为核心,完整精彩的演练了数据结构、算法、设计模式、数据库、大数据高并发检索、文件重定向、多线程同步、进程通讯、黑客劫持技术、网络安全、加密解密,以及各种精彩的小项目等,非常适合大家学习!
  • 2015年06月25日 12:11

C++中static,const,mutable关键字

1、空类默认生成的成员 class Empty{}; Empty();//默认构造函数 Empty(const Empty&);//默认拷贝构造函数 ~Empty();//默认析构函数 Em...
  • bv1315008634
  • bv1315008634
  • 2017-02-10 20:33:09
  • 117

【C++】类与关键字static、const、extern的简单分析

一、类 1.类是什么:         类是一种复杂的数据类型,它是将不同类型的数据和与这些数据相关的操作封装在一起的集合体。这有点像C语言中的结构,唯一不同的就是结构没有定义所说的“数据相关的操作”...
  • lz201788
  • lz201788
  • 2017-09-15 21:36:18
  • 98

谈谈explicit关键字

转载自:http://blog.csdn.net/fornormandy/article/details/79512 今天看到公司的代码内有大量的explicit关键字,但是老版的MSDN内...
  • ManFred2ManFred
  • ManFred2ManFred
  • 2013-07-25 17:47:30
  • 320

数组指针和指针数组和mutable和explicit和static和const关键字

http://blog.csdn.net/hackerwin7/article/details/20064541 int *a[10] :数组指针。数组a里存放的是10个int型指针 int (...
  • lqglqglqg
  • lqglqglqg
  • 2015-08-19 15:51:59
  • 225

C++ mutable关键字

引言:对于类的成员函数来说,如果它不修改类的状态,一般将其声明为const函数. 但是如果我们想在类的const成员函数中修改与类的状态无关的成员变量,那么该怎么做呢?答案是使用mutable关键字。...
  • u012878643
  • u012878643
  • 2017-05-07 21:10:12
  • 116

谈谈explicit关键字zz

谈谈explicit关键字作者:ForNormandy
  • linrix
  • linrix
  • 2006-11-26 10:06:00
  • 802

Caffe2源码理解系列之存储

Caffe2存储Caffe2中的存储结构层次从上到下依次是Workspace, Blob, Tensor。Workspace存储了运行时所有的Blob和实例化的Net。Blob可以视为对任意类型的一个...
  • a_1937
  • a_1937
  • 2017-11-13 18:20:48
  • 699

C++基础::mutable 关键字

mutable 是对 const 型函数的补充,因为 const 的条件太强了
  • lanchunhui
  • lanchunhui
  • 2016-03-15 22:35:55
  • 599

C++关键字详解

C/C++中的关键字 C/C++中的关键字如下:   注:上表中为C++98/03中的63个关键字,其中红色标注为C语言中的32个关键字。C++11中有73个关键字,新增加的...
  • scmuzi18
  • scmuzi18
  • 2016-12-16 18:53:43
  • 10358
收藏助手
不良信息举报
您举报文章:auto/register/volatile/static/const/mutable
举报原因:
原因补充:

(最多只允许输入30个字)