C++ const 关键字的使用总结

const 限定符

C++ const 允许指定一个语义约束,编译器会强制实施这个约束,允许程序员告诉编译器某值是保持不变的。如果在编程中确实有某个值保持不变,就应该明确使用const,这样可以获得编译器的帮助。

const 与常量

①.const 修饰变量

用 const 修饰一个变量,表示该变量一旦创建,则值不可以被更改;定义一个 const 变量,则必须进行初始化。

const int a = 12;//编译时初始化
const int b = getsize();//运行时初始化
a = 10;//报错,const 变量禁止赋值

②.初始化和 const

当用一个对象对初始化另外一个对象时,他们是不是 const 都无关紧要,因为拷贝不改变原对象内容。

int i = 42;
const int c = i;// i 的值 拷贝给 c
int j = c;

③.extern const

一个对象可以有多次声明,但定义只能一次。如果要在多个文件之间共享 const 对象,必须在变量定义之前添加 extern 关键字。

// test1.cpp
extern const int a = 10; //定义一个 const 变量 a,该常量能被其他文件访问

//test2.cpp
extern const int a;// 仅声明一个 const 变量 a,该常量的定义可以在其他文件中找到

禁止在头文件中用 extern 定义变量,若该头文件被多个文件包含时,将会出现重复定义错误。

// test.h
extern const int a = 10; 

// test1.cpp
#include "test.h"
// 编译出错,重复定义错误

④.const 和 #define

#define 是在编译的预处理阶段起作用;而 cons t是在 编译、运行的时候起作用。

#define 只是简单的字符串替换,没有类型检查;const 定义的常量,在编译时进行严格的类型检验,可以避免出错。

#define 只是进行展开,有多少地方使用就替换多少次,内存中有若干个备份;const 定义的只读变量在程序运行过程中只有一份备份。

因此对于单纯常量,最好以 const 对象替换 #define。

const 与引用

①.const 的引用

可以把引用绑定到 const 对象上,称为对常量的引用;对常量的引用不能被用做修改它所绑定的对象。

const int c = 1024;
const int &r = c;// r 是 c 的引用

②.引用非 const 对象

常量引用仅对引用可参与的操作进行了限定,对引用对象本身是不是常量未做限定。

int i= 12;
const int &r = i;// r 是常量引用,但绑定的对象 i 非 const

const 与指针

①.指向常量的指针

要想存放常量对象的地址,只能使用指向常量的指针;指向常量的指针不能用于改变其所指对象的值。

const a = 3;// a 是一个常量
int *p = &a;//错误 , p 是一个普通指针
const int *p1 = &a;// p1 是一个指向常量的指针 

同引用,指向常量的指针对其所指对象是否是常量没有限制。

②.顶层 const

当关键字 const 出现在星号的右边,则为:顶层 const ;表示指针本身是个常量,不能改变指针本身的值。

int i = 2;
int * const ptr= &i;//ptr是一个顶层const,将一直指向 i,不能改变 ptr 的值

③.底层 const

当关键字 const 出现在星号的左边,则为:底层 const ;表示指针所指对象是个常量,不能改变所指对象的值。

int i = 2;
const int * ptr= &i;//ptr是一个底层const,可以改变 ptr 的值,但不能改变所指对象的值

const 与函数

①.const 修饰函数参数

可以表示传递过来的参数,在函数内不可以被修改;并无实际意义,因为函数会自动产生临时变量复制实参值,并不会对原对象进行更改。

void int f1(const int a)
{
	// 在函数内不可以改变 a 的值
}

可以表示参数指针所指的内容为常量,不可以改变。

void int f2(const int *a)
{
	// 在函数内不可以改变 *a 的值
}

可以表示参数指针本身为常量,不可以更改;也无实际意义,因为参数指针也是形参。

void int f3(const int * const a)
{
	// 在函数内不可以改变 a 的值
}

自定义类型的参数传递,需要临时对象复制参数,对于临时对象的构造,需要调用构造函数比较浪费时间,因此采取引用传递的方法。可以用 const 限定 增加效率同时防止被修改。

void int f4(const T &  a)
{
	// 在函数内不可以改变 a 的值
}

②.const 修饰函数返回值

函数返回值是值传递时,用 const 修饰返回值没有任何意义,因为函数会把返回值复制到外部临时的存储单元中。

const int f1();//

函数返回值类型是指针并用 const 修饰时,该返回值只能被赋给加const 修饰的同类型指针。

const int * f2();//调用时,const int * p1 = f2();
int * const f3();//调用时,int * const p2= f3();

一般情况下,函数的返回值为某个对象时,如果将其声明为 const 时,用于限制不能将函数表达式作为左值使用。

const int & min ( int &i, int &j);
min(a,b) = 4;//出错

const 与类

①.const 修饰成员变量

用 const 修饰类的成员变量,表示成员常量,不可以被修改,也只能再初始化列表中被赋值

class A
{
	const int val;//成员常量不可以被修改
    A(int v):val(x){};//只能再初始化列表中赋值
}

②.const 修饰成员函数

用 const修饰类的成员函数,则该成员函数不能修改类中任何成员,一般写在函数的最后来修饰。

class A
{
	void function() const;//不可以修改对象的成员变量,也不能调用非 const 成员函数
}

③.const 修饰类对象

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

用 const 修饰的对象,该对象的任何非 const 成员函数都不能被调用。

class A
{
	void function1() const;
    void function2() ;
}
const A *obj = new A();
A->function1();//正确
A->function2);//错误,const 对象只能调用 const 成员函数

④.const 修饰成员函数修改成员变量

可以使用 mutable 关键字修饰成员,则该变量在 const 成员函数中也可以被修改。

class A
{
    mutable int _ct;
	void function() const
    {
        _ct++;//正确
    };
}

const 转换

①.去 const 限定

使用 const_cast 可以去除变量的 const 限制:常量指针被强制转为非常量指针,仍然指向原来对象;常量引用被强制转为非常量引用,仍然指向原来对象;常量对象被强制转为非常量对象。

const  A *obj = new A();//A 指向的对象不可用被更改
A * ptr = const_cast<A*>(obj);// ptr 和 obj 指向同一个对象,ptr 可以更改对象

const A a;
A b =  const_cast<A>(a);//去 const 属性后赋值给一般变量

②.增加 const 限定

也可以使用 const_cast 、 static_cast 将非 const 对象增加 const 限定。

A *obj = new A();
const  A * ptr = static_cast<const A*>(obj);//obj 增加 const 限定 

在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值