C/C++变量详解

2015/12/03 - C/C++

C++成员变量、成员初始化列表

class test  
{  
    private:  
        int a;//普通成员  
        const int b;//常量成员  
        static int c;//静态成员  
        static const int d;//静态常量成员  
        int &e;//引用类型成员  
        int* f;//指针类型成员
        //int* &g;const int* h; 等等
};

成员变量的初始化有且仅有两种:1、“=”赋值。2、成员初始化列表。其中只能用方法2的有常量成员(不包括静态的)、引用类型成员。

静态成员和静态常量成员由于是类共有的,不是属于某一个对象,因此不能在构造函数中初始化

静态成员(这里不包括静态常量成员)必须在类外初始化

成员变量的初始化顺序只与声明的顺序一致,与成员初始化列表顺序无关

class test  
{  
    //int a=1;//错误:对象没有构造,尚未分配内存空间  
    int a;  
    const int b;  
    //static int c=1;//错误:不可以在声明时初始化  
    static int c;  
    const static int d=1;//唯有该类型可以这样  
    int &e;//引用类型必须用成员初始化列表  
    public:  
    test(int _e):b(1),e(_e)/*引用初始化必须为左值*/{}  
};  
int test::c=1;  
const int test::d=1;//也可以这样初始化 

变量修饰关键字-restrict

restrict只用于限定指针。用于告知编译器,所有修改该指针所指向内容的操作全部都是基于该指针的,即不存在其它进行修改操作的途径。这样可以帮助编译器进行更好的代码优化,生成更有效率的汇编代码

const

一、const变量

对于内置算术类型变量,声明为const之后是不允许改变变量的值的。也因为这样,const变量在声明的时候必须进行初始化

const int i=0;   
i=2;//非法!不允许改变 
const int a;//错误,要进行初始化

二、const引用

引用初始化绑定给一个变量之后绑定是无法改变的,所以对引用的const主要在于能否用引用来改变绑定变量的值

1、用const引用绑定一个const变量值的时候,原值无法改变,也不能通过引用改变变量的值

const int i=3;  
const int &r=i;  
i=2;//错误  
r=2;//错误

2、用const引用绑定一个非const变量值的时候,原值可以改变,但是不能通过引用改变。

int i=3;  
const int &r=i;  
i=2;//正确  
r=2;//错误  

3、不能用非const引用绑定一个const变量。

const int i=3;  
int &r=i;//错误  

4、当引用为const时,可以把“它能够转换成自己类型的值”给引用

double pi=3.14;  
const int &r=p;//正确,并且r=3  
const int &r2=3;//正确,r2=3 

这里需要说明的是r并没有引用pi,相反在进行这个操作的时候,分配了专门的内存来存放r所引用的位置,并且值为3,类型为整形。r值到达这块内存的唯一接口。

三、const指针

int i=3;  
const int *p1=&i;//不可以通过指针改变i  
int *const p2=&i;//不可以改变指针的指向  
const int *const p3=&i;//既不可以改变i,也不可以改变指向 

四、top-level const和low-levelconst

C++中把直接对变量内存单元中的const限制称为top-level const,即无法改变内存中的值。把对间接指向和引用的值的const限制称为low-level const即无法改变所指向和所引用的值。在两个变量进行赋值操作时,必须要有同样的level才可以。

1、top-level可以忽略掉

int i=0;//non-level  
int *const p=&i;//top-level  

2、low-level不可以忽略

const int *p1=&i;  
int *p2=p1;//错误  因为p1是low-level而p2不是,所以不能进行p2=p1的操作。

3、在右边的non-leve可以转换为左边的low-level。 而反过来不可以

int i =0;
int *p1=&i;  
const int *p2=p1;//ok  
p1=p2;//wrong因为p2具有low-level而p1没有,所以可以p2=p1而不能p1=p2。 

static

一、面相过程(C)设计中的static

1、静态全局变量

  • 在全局变量前,加上关键字static。
  • 该变量在全局数据区分配内存(详情参考)。
  • 未经初始化的静态全局变量会被程序自动初始化为0。
  • 静态全局变量在声明它的整个文件都是可见的,而在文件之外是不可见的(其它文件中可以定义相同名字静态变量,不会发生冲突)。 

2、静态局部变量

  • 每当程序运行到该语句时都会给该局部变量分配栈内存。但随着程序退出函数体,系统就会收回栈内存,局部变量也相应失效。
  • 静态局部变量在程序执行到该对象的声明处时被首次初始化,即以后的函数调用不再进行初始化
  • 静态局部变量一般在声明处初始化,如果没有显式初始化,会被程序自动初始化为0;
  • 它始终驻留在全局数据区,直到程序运行结束。但其作用域为局部作用域,当定义它的函数或语句块结束时,其作用域随之结束;

3、静态函数

  • 声明函数的文件当中可见,不能被其它文件使用。

二、面相对象(C++)的static关键字

1、静态数据成员

  • 该数据成员就是类内的静态数据成员。无论这个类的对象被定义了多少个,静态数据成员在程序中也只有一份拷贝,由该类型的所有对象共享访问。
  • 静态数据成员存储在全局数据区。静态数据成员定义时要分配空间,所以不能在类声明中定义。
  • 遵从public,protected,private访问规则。
  • 静态数据成员没有进入程序的全局名字空间,因此不存在与程序中其它全局名字冲突的可能性。
  • 可以实现信息隐藏。静态数据成员可以是private成员,而全局变量不能。

2、静态成员函数

  • 静态成员函数与静态数据成员一样,都是类的内部实现,属于类定义的一部分,而不是对象
  • 普通的成员函数一般都隐含了一个this指针,this指针指向类的对象本身,因为普通成员函数总是具体的属于某个类的具体对象的。通常情况下,this是缺省的。如函数fn()实际上是this->fn()。但是与普通函数相比,静态成员函数由于不是与任何的对象相联系,因此它不具有this指针。从这个意义上讲,它无法访问属于类对象的非静态数据成员,也无法访问非静态成员函数,它只能调用其余的静态成员函数。由于没有this指针的额外开销,因此静态成员函数与类的全局函数相比速度上会有少许的增长
  • 出现在类体外的函数定义不能指定关键字static;

typename

1、用在模板定义里,标明其后的模板参数是类型参数

template<typename T, typenameY>

2、模板中标明“内嵌依赖类型名”

typenameiterator_traits<_InputIter>::difference_type __n = 0; //变量定义,说明difference_type是类型而不是一个类静态变量。

命名规范


如果文章对您有帮助,欢迎扫描下方二维码赞助(一分也是爱噢),谢谢

Search

    一分也是爱噢 一分也是爱

    目录