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的意义完全相同,只是不同的程序员具有不同的编码习惯,我们要熟悉所有的这三种用法,下面给出一段代码,来说明他们三个的区别:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <vector>
#include <limits.h>
#include <iostream> using namespace std; int main(int argc, char *argv[])
{
const char * p1 = new char []();
for( int i = ; i < ; i++ )
{
cout<<p1[i]<<endl;
} p1[] = 'a';//错误!const char * p指向一个不可改变的对象
cout<<p1[]<<endl; char const * p2 = new char[];
p2[] = 'a';//错误!同上
cout<<p2[]<<endl; char ch[] = "abcd";
delete [] p1;
p1 = ch;//正确 指针的值可以修改
cout<<p1<<endl; char * const p3 = new char[];
p3[] = 'a';//正确!
cout<<p3[]; delete [] p3;
p3 = ch;//错误 指针的值不可以修改
cout<<p3<<endl;
}
在第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其内部成员不可修改,否则可以自由修改。例如如下代码:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <vector>
#include <limits.h>
#include <iostream> using namespace std; class MyIntArray
{
private:
static const int a = ;
int p[a];
public:
MyIntArray()
{
for( int i = ; i < a ; i++ )
{
p[i] = i;
}
}
const int & operator [](int n) const
{
return p[n];
}
int & operator [](int n)
{
return p[n];
}
}; int main(int argc, char *argv[])
{
MyIntArray array;//定义一个非const对象
cout<<array[]<<endl;//输出20
array[] = ;//正确,调用非const版本的[]
cout<<array[]<<endl;//输出6 const MyIntArray carray;//定义一个const对象
cout<<carray[]<<endl;//输出20
carray[] = ;//错误!调用const版本的[]操作符
cout<<carray[]<<endl;
}
对于一个非const对象array我们可以自由的把array[0]作为左值,而对于一个const对象carray我们则不可以把其作为左值。由此可发现const的强大之处。
C++ 中的 const 详解的更多相关文章
- C++中的const详解
const的用法,特别是用在函数后面 在普通的非 const成员函数中,this的类型是一个指向类类型的 const指针.可以改变this所指向的值,但不能改变 this所保存的地址. 在 const ...
- 【转载】C/C++中extern关键字详解
1 基本解释:extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义.此外extern也可用来进行链接指定. 也就是说extern ...
- C++中的STL中map用法详解(转)
原文地址: https://www.cnblogs.com/fnlingnzb-learner/p/5833051.html C++中的STL中map用法详解 Map是STL的一个关联容器,它提供 ...
- ALSA声卡驱动中的DAPM详解之七:dapm事件机制(dapm event)
前面的六篇文章,我们已经讨论了dapm关于动态电源管理的有关知识,包括widget的创建和初始化,widget之间的连接以及widget的上下电顺序等等.本章我们准备讨论dapm框架中的另一个机制:事 ...
- ALSA声卡驱动中的DAPM详解之六:精髓所在,牵一发而动全身
设计dapm的主要目的之一,就是希望声卡上的各种部件的电源按需分配,需要的就上电,不需要的就下电,使得整个音频系统总是处于最小的耗电状态,最主要的就是,这一切对用户空间的应用程序是透明的,也就是说,用 ...
- ALSA声卡驱动中的DAPM详解之四:在驱动程序中初始化并注册widget和route
前几篇文章我们从dapm的数据结构入手,了解了代表音频控件的widget,代表连接路径的route以及用于连接两个widget的path.之前都是一些概念的讲解以及对数据结构中各个字段的说明,从本章开 ...
- ALSA声卡驱动中的DAPM详解之三:如何定义各种widget
上一节中,介绍了DAPM框架中几个重要的数据结构:snd_soc_dapm_widget,snd_soc_dapm_path,snd_soc_dapm_route.其中snd_soc_dapm_pat ...
- php中关于引用(&)详解
php中关于引用(&)详解 php的引用(就是在变量或者函数.对象等前面加上&符号) 在PHP 中引用的意思是:不同的变量名访问同一个变量内容. 与C语言中的指针是有差别的.C语言中的 ...
- JavaScript正则表达式详解(二)JavaScript中正则表达式函数详解
二.JavaScript中正则表达式函数详解(exec, test, match, replace, search, split) 1.使用正则表达式的方法去匹配查找字符串 1.1. exec方法详解 ...
随机推荐
- Linux下的lds链接脚本基础
转载:http://soft.chinabyte.com/os/104/12255104.shtml 今天在看uboot引导Linux部分,发现要对链接脚本深入了解,才能知道各个目标文件的内存分布 ...
- iOS企业级开发者计划的申请流程
第一步:访问苹果企业版iDP网址:https://developer.apple.com/programs/ios/enterprise/点击Apply Now按钮,开始申请流程. 第二步:点击App ...
- WPF 之 线程使用
但凡涉及到图形界面,往往的设计都是不支持或者不推荐使用多个线程操作界面内容.而且通常会有一个专门的线程调度器来处理任务线程和界面线程的问题. 下面提供两个方案: 1.使用Dispatcher.Begi ...
- Linux下mongodb安装
1>设置mongoDB目录 cd /home/apps 附:centOS下创建目录命令 mkdir /home/apps 2>下载mongodb curl -O http:// ...
- CALayer实现点击屏幕放大或者缩小的一个圆
#import "ViewController.h" #define WIDTH 50 @interface ViewController () @end @implementat ...
- [WinForm] TableLayoutPanel和FlowLayoutPanel的使用
这篇文章主要跟大家分享下,在配餐系统的开发中,对tableLayoutPanel 和 flowLayoutPanel 控件的使用方法和技巧 ——后附上 测试demo, 相信需要的朋友下载看后能很快的知 ...
- 读取Excel文件的两种方法
第一种方法:传统方法,采用OleDB读取EXCEL文件, 优点:写法简单,缺点:服务器必须安有此组件才能用,不推荐使用 private DataSet GetConnect_DataSet2(stri ...
- asp.net小结
ASP.net是是一种使嵌入网页中的脚本可由因特网服务器执行的服务器端脚本技术,主要用于WEB开发,与我们以前接触CS开发相比,虽然相似点不少,但不同点也是有很多的,我来简单的总结一下. 一.控件 A ...
- HTML <input> 标签的 maxlength 属性
前端的表单,需要进行验证. 结合JS表单验证框架,写了很多前端验证的代码. 其中,有这么一个需求:用户最多只能输入10个字符. 按照惯性,肯定是会去写JS表单验证了. 实际上,根本没有必要. HTML ...
- php用curl获取远端网页内容
<?php $url="http://www.baidu.com";$cc=curl_init(); curl_setopt($cc,CURLOPT_URL,$url); c ...