C++中const关键字用法详解

目录

(一)什么是const

(二)const修饰变量的属性

(三)const的用法简介

(四)const与指针的使用

1.const与指针

2.const与字符常量:

(五)const与类的对象

1.const修饰对象

const修饰成员函数的用法

const修饰成员函数的原理

2.const与函数重载:

3.const修饰成员变量


(一)什么是const

constant在中文中翻译为常量,const是constant的形容词,翻译为恒定的,即常量所具有的特性。在c++中,const用来修饰一个变量,使其拥有一个恒定的值,不可以被改变。

(二)const修饰变量的属性

const修饰的变量仍然是变量而不是常数,遵循变量的特性-----如本地变量进入函数中才有,在离开函数后被清除,所以const修饰的本地变量在离开后也会被清除。

(三)const的用法简介

1)const修饰变量时,变量类型与const关键字的位置可随意调换

const int a = 0 ; //也可写作int const a = 0 ;

2)在定义const变量时必须进行初始化,除非在前面加上extern关键字变为声明,意思是告诉编译器存在这样一个const变量,不能被修改。

(四)const与指针的使用

1.const与指针

指针涉及到指针本身指针所指向的东西,所以const与指针结合存在三种情况:

1)第一种是指针本身为const,即指针不能指向其他内存,因此不能进行指针的加减运算:

char * const q = "abc";//q is const
*q='c';//OK
 q++;//ERROR

2)第二种是通过指针所指的东西是const,即不能通过指针修改它所指的变量的值,而不是指针指到哪里,哪里内存单元就变为const恒定的(此处较晦涩,需要梳理一下逻辑,const修饰指针所指的东西强调通过指针不能修改):

const char *p="ABCD";//(*p) is a const char
p++;//OK
*p='b';//ERROR

针对第二种情况,下面举两个例子:

例1:

#include<iostream>
using namespace std;
int main()
{
    int a=1;
    int const *p = &a;//指针p指向变量a

    //(*p)++;//error:不能通过指针修改它所指的变量的值
    a++;//通过其他途径修改了指针所指的变量的值

    cout<<*p<<endl;

}

输出结果:

这里的p指向a,而const修饰p所指的东西,因此我们无法通过指针p修改a的值,也就是*p不能作为左值,但这并不代表p所指的内存是const那种无法修改的,我们可以直接去改变a的值,这是可行的。

例2:

const int ci = 0;

int *ip;
const int *cip;

ip=&ci;  //Error:ci为const变量,其值不能修改,故不能将其地址传给一般指针
cip=&ci; //OK:指针指向const变量,可以将ci的地址传给指针

3)第三种并不常用,即用两个const分别修饰指针和指针所指向的东西

int i = 1;
const int* const p = &i;

2.const与字符常量:

在c语言中我们也遇到类似情况,使字符指针指向一个字符串常量,接着去修改某一位置的字符,但是运行输出hello world后会异常终止,代码如下:

#include<iostream>
using namespace std;
int main()
{
   char *s = "hello world";
   cout<<s<<endl;
   s[0]='b';
   cout<<s<<endl;
}

这是因为"hello world"是一个常量,被放在内存区的代码段中,而代码段不能被改写,若尝试改写,程序会终止,实际上定义的指针是指向const变量的:

const char *s = "hello world";

因此我们无法修改它的内容,如果想修改应该怎么做呢-----将const指针变为数组:

 char s[] = "hello world";

整个数组在堆栈里面,因此要分配很大的空间,指针中"="的作用是将代码段中"hello world"的地址传给指针,在数组中的作用是把代码段中"hello world"拷贝到堆栈中,我们通过打印各自的地址来验证其在内存中的位置。

如果我们调用函数时,把整个对象传进去可能会耗费很大空间,如果传入一个地址进去会方便很多。当我们将对象的地址传入某些函数时,很可能对象的值被修改:

如下代码:

#include<iostream>
using namespace std;
void f(int *i)
{
    (*i)++;
}
int main()
{
    int p=3;
    f(&p);
    cout<<"p="<<p<<endl;
}

 为了保护对象p的值不被函数修改,我们可以用const修饰对象起到保护的作用:

const int p = 3 ;

这样会阻止编译的通过,从而保护p的值不被改变。

(五)const与类的对象

1.const修饰对象

const修饰的对象里面的值不能被修改,但我们无法判断对象中的成员函数是否会更改对象内的某些数据,所以我们可以在某些成员函数中加入const:

const修饰成员函数的用法

1)在定义和声明中同时加上const关键字

2)不修改对象内数据的成员函数应该用const修饰

3)const修饰的成员函数对于const修饰的对象是安全可靠的

const修饰成员函数的原理

this指针指向的内容是const,即我们不能通过this指针来修改对象中的数据(this是class类型的指针)

2.const与函数重载:

成员函数中同名函数,其中一个用const修饰,可被认为是函数重载而非函数重名,代码如下:

#include<iostream>
using namespace std;
class A
{
    int i;
public:
    A():i(0) {}
    void f()
    {
        cout<<"f()"<<endl;
    }
    void f()const
    {
        cout<<"f() const "<<endl;
    }
};

int main()
{
    const A a;
    a.f();
    return 0;
}

运行结果

 可以被认为是函数重载是因为两个f函数的参数不同

void f(){...}      //即void f(A* this)
void f()const{...} //即void f(const A* this)

3.const修饰成员变量

const修饰的成员变量必须在初始化列表中初始化

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值