C++ 中的 const 详解

作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4235721.html

1.为什么使用 const int 而不使用 #define

在使用#define时,比如#define Max 10000,如果出现错误,编译器并不会提示Max,因为在预处理阶段已经把Max替换成了10000,因此编译器会莫名其妙的提示10000这个数字出现了错误,从而不利于程序debug,但是如果使用const int Max=10000,编译器就会准确的提示Max有错误,从而可以轻易地定位。

2.如何正确的使用 const

1)const 修饰变量

对于一个字符指针的定义char * p;加上const关键字时无非有三种方法,即把const放在前中后三个位置。那么他们之间有什么区别呢?

  1 const char * p1;//表示p1指向了的字符串不可更改

  2 char const * p2;//同上

  3 char * const p3;//表示p2指针的指向不可更改

注意1和2的意义完全相同,只是不同的程序员具有不同的编码习惯,我们要熟悉所有的这三种用法,下面给出一段代码,来说明他们三个的区别:

 1 #include <stdlib.h>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #include <vector>
 5 #include <limits.h>
 6 #include <iostream>
 7
 8 using namespace std;
 9
10 int main(int argc, char *argv[])
11 {
12     const char * p1 = new char [10]();
13     for( int i = 0 ; i < 10 ; i++ )
14     {
15         cout<<p1[i]<<endl;
16     }
17
18     p1[0] = ‘a‘;//错误!const char * p指向一个不可改变的对象
19     cout<<p1[0]<<endl;
20
21     char const * p2 = new char[10];
22     p2[0] = ‘a‘;//错误!同上
23     cout<<p2[0]<<endl;
24
25     char ch[5] = "abcd";
26     delete [] p1;
27     p1 = ch;//正确 指针的值可以修改
28     cout<<p1<<endl;
29
30     char * const p3 = new char[100];
31     p3[0] = ‘a‘;//正确!
32     cout<<p3[0];
33
34     delete [] p3;
35     p3 = ch;//错误 指针的值不可以修改
36     cout<<p3<<endl;
37 }

在第18行和第22行中,由于指针所指向的对象不可修改,因此会出现错误,而在35行处其指针的指向不可修改,因此不可把它指向另一个地址。

2)const 修饰函数

const不仅可以修饰变量,也可以修饰函数,当const修饰函数,例如[]符重载操作, int & operator [](int n) 时有两个位置可以放置:

  1 const int & operator[](int n);

  2 int & operator[](int) const;

前者指其返回值不可修改,例如对于一个const对象 cint,我们不可以使用cin[0]=3,这种左值的方式对其进行赋值,因为其是一个const对象,应该不能够对其内部值进行修改。

而后者的意思是该[]操作符函数内部不对其对象内部进行修改,是一个const函数,如果其函数实现对内部成员进行了修改,则会报错。

对于一个[]操作符,我们往往使用重载的方式来实现其const版本和非const版本,在const版本中,如果对象定义为const其内部成员不可修改,否则可以自由修改。例如如下代码:

 1 #include <stdlib.h>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #include <vector>
 5 #include <limits.h>
 6 #include <iostream>
 7
 8 using namespace std;
 9
10 class MyIntArray
11 {
12     private:
13         static const int a = 100;
14         int  p[a];
15     public:
16         MyIntArray()
17         {
18             for( int i = 0 ; i < a ; i++ )
19             {
20                 p[i] = i;
21             }
22         }
23         const int & operator [](int n) const
24         {
25             return p[n];
26         }
27         int & operator [](int n)
28         {
29             return p[n];
30         }
31 };
32
33 int main(int argc, char *argv[])
34 {
35     MyIntArray array;//定义一个非const对象
36     cout<<array[20]<<endl;//输出20
37     array[20] = 6;//正确,调用非const版本的[]
38     cout<<array[20]<<endl;//输出6
39
40     const MyIntArray carray;//定义一个const对象
41     cout<<carray[20]<<endl;//输出20
42     carray[20] = 6;//错误!调用const版本的[]操作符
43     cout<<carray[20]<<endl;
44 }

对于一个非const对象array我们可以自由的把array[0]作为左值,而对于一个const对象carray我们则不可以把其作为左值。由此可发现const的强大之处。

时间: 2024-11-10 16:09:41

C++ 中的 const 详解的相关文章

C++中的const详解

const的用法,特别是用在函数后面 在普通的非 const成员函数中,this的类型是一个指向类类型的 const指针.可以改变this所指向的值,但不能改变 this所保存的地址. 在 const成员函数中,this的类型是一个指向 const类类型对象的 const指针.既不能改变 this所指向的对象,也不能改变 this所保存的地址.   关键字:Const,Const函数,Const变量,函数后面的Const 看到const关键字,C++程序员首先想到的可能是const常量.这可不是

c/c++中const详解

c/c++中const详解 来自http://blog.csdn.net/lwbeyond/article/details/6187501 一. cons 的作用 (1) 可以定义 const 常量 const int Max=100; int Array[Max]; (2) 可以保护被修饰的东西,防止意外的修改,增强程序的健壮性 如果在函数体内修改了i,编译器就会报错: void f (const int i) { i=10;//error! } (3) 为函数重载提供了一个参考 class 

MySQL中EXPLAIN命令详解

explain显示了mysql如何使用索引来处理select语句以及连接表.可以帮助选择更好的索引和写出更优化的查询语句. 使用方法,在select语句前加上explain就可以了: 如: explain select surname,first_name form a,b where a.id=b.id EXPLAIN列的解释: table:显示这一行的数据是关于哪张表的 type:这是重要的列,显示连接使用了何种类型.从最好到最差的连接类型为const.eq_reg.ref.range.in

C#.net 中 修饰符 详解 (来自MSDN)

自己理解的不够深刻,无奈基础较差!记上一笔,记忆深刻些,哈哈…… 1. 访问修饰符 public 同一程序集中的任何其他代码或引用该程序集的其他程序集都可以访问该类型或成员. private 只有同一类或结构中的代码可以访问该类型或成员. protected 只有同一类或结构或者此类的派生类中的代码才可以访问的类型或成员. internal 同一程序集中的任何代码都可以访问该类型或成员,但其他程序集中的代码不可以. protected internal 由其声明的程序集或另一个程序集派生的类中任

Ossim 中漏洞扫描详解

Ossim 中漏洞扫描详解 Openvas是一套开源漏洞扫描系统,如果手动搭建需要复杂的过程,花费不少人力和时间成本,此文主要针对OSSIM平台下如何以图形化方式操作漏洞扫描的过程. 准备工作:首先确保没有运行的扫描进程和任务 扫描漏洞同时升级漏洞库会导致升级失败. 第一步:同步插件 #openvas-nvt-sync 同步数万个插件时间比较长,可以去喝杯咖啡啦,或者了解一下插件的组成. 表1 Openvas主要脚本分类及分布情况 规则名称 数量 备注 IIS_frontpage_DOS_2.n

Python中time模块详解

在Python中,与时间处理有关的模块就包括:time,datetime以及calendar.这篇文章,主要讲解time模块. 在开始之前,首先要说明这几点: 在Python中,通常有这几种方式来表示时间:1)时间戳 2)格式化的时间字符串 3)元组(struct_time)共九个元素.由于Python的time模块实现主要调用C库,所以各个平台可能有所不同. UTC(Coordinated Universal Time,世界协调时)亦即格林威治天文时间,世界标准时间.在中国为UTC+8.DST

转:LoadRunner中参数化技术详解

LoadRunner中参数化技术详解 LoadRunner在录制脚本的时候,只是忠实的记录了所有从客户端发送到服务器的数据,而在进行性能测试的时候,为了更接近真实的模拟现实应用,对于某些信息需要每次提交不同的数据,或者使用多个不同的值进行循环输入.这时,在LoadRunner中就可以进行参数化设置,以使用多个不同的值提交应用请求. [参数化]使用指定数据源中的值来替换脚本录制生成的语句中的参数. [好处] l  减少脚本的大小 l  提供使用不同的值执行脚本的能力,更加真实的模拟现实应用. [参

Android技术18:Android中Adapter类详解

1.Adapter设计模式 Android中adapter接口有很多种实现,例如,ArrayAdapter,BaseAdapter,CursorAdapter,SimpleAdapter,SimpleCursorAdapter等,他们分别对应不同的数据源.例如,ArrayAdater对应List和数组数据源,而CursorAdapter对应Cursor对象(一般从数据库中获取的记录集).这些Adapter都需要getView方法返回当前列表项显示的View对象.当Model发生改变时,会调用Ba

java中static作用详解

static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,但是Java语言中没有全局变量的概念. 被static修饰的成员变量和成员方法独立于该类的任何对象.也就是说,它不依赖类特定的实例,被类的所有实例共享. 只要这个类被加载,Java虚拟机就能根据类名在运行时数据区的方法区内定找到他们.因此,static对象可以在它的任何对象创建之前访问,无需引用任何对象. 用public修饰的static成员变量和成员方法本质是全局变量和全局方法,当声明它类