理解C++关键字(5)---理解const关键字

在《Effective c++》中,条款02指出:尽可能的使用const替换define;条款03指出:尽可能的使用const。可见,define在C++中不太受欢迎。本文将总结const的一般用法,并说明其和define两者的区别。


1、const的一般用法与特点

(1)将常见的数据类型约束为“不可被改动的对象”

例如一下语句:cont int a=5;将整型变量a声明为常量,即“只读”。

(2)提高运行效率

在上述语句开始编译时,编译器通常并不为变量a分配存储空间,而是将其保存在符号表中,这使得它在编译期间成为一个常量,少了存储与读内存的操作,提高运行效率。

(3)节省内存

在程序运行期间,只进行一次拷贝,并且在静态存储区中为const变量分配内存。比如,执行下面的语句:

const int a=5;
int b=a;     //在静态存储区分配内存
int c=a;     //不再进行内存分配
(4)const修饰指针

已知const int a1=3;
一般有四种情形:
1. const int *a=&a1; //a是一个指向常整型数的指针,即指针可变,而数据不可变
2. int *const a=&a1; //a是一个指向整型数的常指针,即指针不可变,数据可变
3. const int *const a=&a1; //a是一个指向常整形数的常指针,即指针不可变,并且数据不可变
4. 另外const int等价于int const

看完有点晕~。下面利用代码解释上面的种种神操作~~~

#include<iostream>
using namespace std;

int main()
{
    int temp[]={3,4,5};     //声明整型数组,数组名为数组的首地址

    const int *a=&temp;     //根据上面的解释,a为指向常整形数的指针,即a指向的整型数不可修改,但指针a可修改
    cout<<"a指向的地址为:    "<<a<<endl;      //运行后,输出“012FF9D4”
    cout<<"a指向的整型数为:   "<<*a<<endl;     //运行后,输出3,即数组首元素
    a++;                    //修改指针a,使其指向下一个地址
    //*a=*a+1;              //修改a指向的整型数。报错,*a为常量,不可修改。符合预期
    cout<<"a指向的地址为:    "<<a<<endl;  //运行后,输出“012FF9D8”,指向下一个地址,即“012FF9D4”+4个字节

    int *const b=temp;    //根据上面的解释,b为指向整型数的常指针,即指针b不可修改,但指针b指向的整型数可修改
    cout<<"b指向的地址为:    "<<b<<endl;      //运行后,输出“012FF9D4”
    cout<<"b指向的整型数为:   "<<*b<<endl;     //运行后,输出3,即数组首元素
    //b++;                   //报错,指针b不可修改
    *b=*b+1;                 //修改指针b指向的整型数
    cout<<"b指向的整型数为:   "<<*b<<endl;     //运行后,输出4,即3+1=4。符合预期

    const int *const c=temp;  //指向常整形数的常指针
    cout<<"c指向的地址为:    "<<c<<endl;      //运行后,输出“012FF9D4”
    cout<<"c指向的整型数为:   "<<*c<<endl;     //运行后,输出3,即数组首元素
    //c++;                   //报错,指针b不可修改
    //*c=*c+1;               //报错,指针b指向的整型数不可修改。符合预期

}
(5)修饰类的成员变量

利用const修饰类的成员变量时,const成员变量只在某个对象的生存期内是“只读”的,而C++可以为一个类同时声明许多对象,从而各个对象的同一个const成员变量值有可能不相同。这就相当于const成员变量为每个对象单独拥有。
由此,可以得出,const类型的成员变量不能在类中定义
那么,怎么来声明和定义一个const类型的成员变量呢?一般有两种方式:

  1. 在类中声明为”const static”类型,在类外利用“const <变量类型> <类名>::<变量名> =<值>”定义;
  2. 在类中声明为”const”类型,在构造函数的初始化列表中定义。

看下面的代码:

#include<iostream>
using namespace std;

class const_test{

    const int a;                    //在类内声明常整型成员变量a,默认为private
    const static int b;             //在类中利用“const static”声明静态常整型成员变量b
    public:
        const_test(int x):a(x){}    //在构造函数的初始化列表中初始化常整型变量x
        ~const_test(){}
};
const int const_test::b=4;          //在类外定义
(6)其他情况

除上面的情形外,const也可以用于下列情形:
1. const也可以声明定义全局变量,并可以在多个文件中使用:
在主文件中,要同时声明并定义,如const int a=3;;在其他文件中使用时,通过extern const int a;实现。
2. const可以修饰类的成员函数,但函数中不能访问非const成员函数,并且不能修改任何成员变量(mutable类型除外);
3. const可以修饰引用,此时引用“只可读”
4. const可以修饰普通函数,函数返回值,函数形参,保持“可读属性”。

2、const比define的优势

主要有以下几方面的区别:

  1. const修饰,编译时进行类型检查,而利用define时,不进行类型检查(因为没有类型……)
  2. 利用const时,只进行一次拷贝,节省内存,而define类似于替换,每次都得调用并分配内存;
  3. 在编译时,通常编译器并不为const修饰的变量分配内存,而放入符号表中,使得其在编译期间成为一个常量,提高效率,而define在预处理阶段就进行替换;
  4. define定义的变量只能作用于单个文件,而const修饰的变量可以跨文件使用;
  5. define只是简单的复制,不进行运算符的运算,如下面的经典例子:
#include<iostream>
using namespace std;

#define a x+y

int main()
{
    int x=1,y=2;
    cout<<a*a<<endl;      //输出5,因为1+2*1+2=5
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值