c++ const static

const作用:

1.定义常量,可以保护被修饰的东西,防止意外的修改,增强程序的健壮性。    

  const int Max = 100; 

  void f(const int i) { i=10;//error! }
      //如果在函数体内修改了i,编译器就会报错

const int  a = 7; 

int  b = a; //it's right 
a = 8;       // it's wrong,

2.便于进行类型检查

  const常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查,而对后者只进行字符替换,没有类型安全检查,并且在字符替换时可能会产生意料不到的错误。

3.可以很方便地进行参数的调整和修改,同宏定义一样,一变都变

4.可以节省空间,避免不必要的内存分配

  const定义常量从汇编的角度来看,只是给出了对应的内存地址,而不是象#define一样给出的是立即数,所以,const定义的常量在程序运行过程中只有一份拷贝,而#define定义的常量

  在内存中有若干个拷贝。

  define PI 3.14159         //常量宏
  const doulbe  Pi=3.14159;  //此时并未将Pi放入ROM中
              ......
  double i=Pi;   //此时为Pi分配内存,以后不再分配!
  double I=PI;  //编译期间进行宏替换,分配内存
  double j=Pi;  //没有内存分配
  double J=PI;  //再进行宏替换,又一次分配内存!

5.提高了效率。编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高

const使用:

1.定义常量:const修饰变量,以下两种定义形式在本质上是一样的。它的含义是:const修饰的类型为TYPE的变量value是不可变的。

       TYPE const ValueName = value; 
         const TYPE ValueName = value;

2.指针使用const

  char* const pContent;  指针本身是常量不可变

  const char *pContent;  指针所指向的内容是常量不可变

3.函数中使用const:

  const修饰函数参数

  a.传递过来的参数在函数内不可以改变(无意义,因为Var本身就是形参)

      void function(const int Var);

  b.参数指针所指内容为常量不可变

      void function(const char* Var);

  c.参数指针本身为常量不可变(也无意义,因为char* Var也是形参)

      void function(char* const Var);

  d.参数为引用,为了增加效率同时防止修改。修饰引用参数时:

      void fun(A a);

      void fun(A const &a);

      第一个函数效率低。函数体内产生A类型的临时对象用于复制参数a,临时对象的构造、复制、析构过程都将消耗时间。而第二个函数直接传递地址,“引用传递”不需要

      产生临时对象,节省了临时对象的构造、复制、析构过程消耗的时间,提高了效率。但光用引用有可能改变a,所以加上const。  

 4.类相关const:

(1)const修饰成员变量
const修饰类的成员函数,表示成员常量,不能被修改,同时它只能在初始化列表中赋值。
    class A
    { 
        …
        const int nValue;         //成员常量不能被修改
        …
        A(int x): nValue(x) { } ; //只能在初始化列表中赋值
     } 

(2)const修饰成员函数
const修饰类的成员函数,则该成员函数不能修改类中任何非const成员函数。一般写在函数的最后来修饰。
    class A
    { 
        …
       void function()const; //常成员函数, 它不改变对象的成员变量.                        

//也不能调用类中任何非const成员函数。
}

对于const类对象/指针/引用,只能调用类的const成员函数,因此,const修饰成员函数的最重要作用就是限制对于const对象的使用。

a. const成员函数不被允许修改它所在对象的任何一个数据成员。

b. const成员函数能够访问对象的const成员,而其他成员函数不可以。

 

(3)const修饰类对象/对象指针/对象引用

const修饰类对象表示该对象为常量对象,其中的任何成员都不能被修改。对于对象指针和对象引用也是一样。

const修饰的对象,该对象的任何非const成员函数都不能被调用,因为任何非const成员函数会有修改成员变量的企图。
例如:
class AAA

    void func1(); 
void func2() const; 

const AAA aObj; 
aObj.func1(); ×
aObj.func2(); 正确
 

https://www.cnblogs.com/JiFfeiYu/p/6697195.html

static:

1.为什么设计static?

      考虑下面的需求:在程序运行过程中,在一个范围内,有一个对象大家共享,而且可以多次使用,状态能够保持,对象的生命周期一直持续到程序运行结束。函数内部定义的变量,在程序执行到它的定义处时,编译器为它在栈上分配空间,大家知道,函数在栈上分配的空间在此函数执行结束时会释放掉,这样就产生了一个问题: 如果想将函数中此变量的值保存至下一次调用时,如何实现? 最容易想到的方法是定义一个全局的变量,但定义为一个全局变量有许多缺点,最明显的缺点是破坏了此变量的访问范围(使得在此函数中定义的变量,不仅仅受此函数控制)。

2.什么时候用static? 需要一个数据对象为整个类而非某个对象服务,同时又力求不破坏类的封装性,即要求此成员隐藏在类的内部,对外不可见。

3.作用:

    a.作用域隐藏。当一个工程有多个文件的时候,用static修饰的函数或变量只能够在本文件中可见,文件外不可见

    b.全局生命周期。用static修饰的变量或函数生命周期是全局的。被static修饰的变量存储在静态数据区(全局数据区),程序运行期间,不能释放,一直到程序终止。

    c.static修饰的变量默认初始化为0且只初始化一次

    d.可以节省内存。static修饰的变量或函数是属于类的,所有对象公有,只有一份拷贝

     因此,不能够将静态函数设置为虚函数
    

注意:1.静态数据成员的值对每个对象都是一样,但它的值是可以更新的。某个类的实例只要对静态数据成员的值更新一次,所有对象存取更新后的相同的值,这样可以提高时间效率

   2.在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,因而只能访问类的static成员,也就是静态变量和静态函数

   3.static类对象必须要在类外进行初始化

class Text
{
    public:
    static int count;
};
 
int Text::count=0;//用static成员变量必须要初始化 
 
int main()
{
    Text t1;
    cout<<t1.count<<endl; 
    return 0;
}

   4.静态成员之间可以相互访问,包括静态成员函数访问静态数据成员和访问静态成员函数;非静态成员函数可以任意地访问静态成员函数和静态数据成员; 静态成员函数不能访问非静态成员函数和非静态数据成员; 

 
 

const static:

class A
{
public:
    A():m(10)                  //const成员必须在构造函数的初始化构造列表中初始化
    {
        q = 40;
    }

    void fun1()const
    {
        m++;                 //错误。const成员是常量,不能改变其值。
        n++;                 //正确。static变量n属于类,但是每个对象的函数都可以访问和改变它。
        q++;                 //错误。const成员函数不能改变数据成员的值。
    }
    static void fun2()
    {
        m++;                 //错误。const成员是常量,不能改变其值。
        n++;                 //正确。static成员函数可以访问和改变static变量的值。
        q++;                 //错误。static成员函数不能访问和改变非static数据成员的值。
    }


    const int m;
    static int n;
    static const int p;
    int q;
};

int A::n = 5;                //static 成员必须在类外初始化,此时不用加关键字static,但是要指定类作用域 A::
const int A::p = 30;         //static const 成员跟static成员一样在类外初始化(而不是在构造函数初始化列表中),记得加上关键字const

1.C++中,const成员不能在类定义处初始化,只能通过构造函数初始化列表进行,并且必须有构造函数

2.static 成员必须在类外初始化

3.static const 成员跟static成员一样在类外初始化(而不是在构造函数初始化列表中),记得加上关键字const

4.static表示的是静态的。类的静态成员函数、静态成员变量是和类相关的,而不是和类的具体对象相关的。

原文地址:https://www.cnblogs.com/ymjyqsx/p/9728789.html