zoukankan      html  css  js  c++  java
  • 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表示的是静态的。类的静态成员函数、静态成员变量是和类相关的,而不是和类的具体对象相关的。

  • 相关阅读:
    Ubuntu 16.04在启动和关机时不显示启动和关机画面且显示详细的命令信息,没有进度条和Logo,或者只有紫色界面,或者没有开机画面等问题解决
    Ubuntu 16.04设置开机关机时显示命令详细信息不显示进度条Logo
    Ubuntu中LightDM是什么(转)
    Linux终止进程的工具kill/killall/pkill/xkill/skill用法区别(转)
    Ubuntu 16.04安装BleachBit清理系统垃圾文件
    Ubuntu 16.04禁用来宾账号(Guest User)
    Java反射 : Declared的作用 ( 例如 : getMethods和getDeclaredMethods )
    java isAssignableFrom instanceof 小结 专题
    java.lang.IllegalArgumentException: Illegal character in query at index ...解决办法
    spring boot使用AbstractXlsView导出excel
  • 原文地址:https://www.cnblogs.com/ymjyqsx/p/9728789.html
Copyright © 2011-2022 走看看