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方法详解 ...
随机推荐
- Robot Framework简介
概述 Robot Framework是一个通用的关键字驱动自动化测试框架.测试用例以HTML,纯文本或TSV(制表符分隔的一系列值)文件存储. 通过测试库中实现的关键字驱动被测软件.Robot Fra ...
- The Socket API, Part 4: Datagrams
转:http://www.linuxforu.com/2011/11/socket-api-part-4-datagrams/ By Pankaj Tanwar on November 1, 2011 ...
- NET开发必备工具之-LINQPad
第一步,下载:http://www.linqpad.net/ 第二步,安装 第三步,打开LINQPad 第四步,添加链接 第五步,输入SQL Server,用户名,密码 第六步,点击OK,成功链接 第 ...
- C++对象内存模型1(堆栈模型)
对象内存模型 一. 栈(Stack) VS. 堆(heap) 栈 由系统自动管理,以执行函数为单位 空间大小编译时确定(参数+局部变量) 函数执行时,系统自动分配一个stack 函数执行结束时,系统立 ...
- iOS H5容器的一些探究(二):iOS 下的黑魔法 NSURLProtocol
来源:景铭巴巴 链接:http://www.jianshu.com/p/03ddcfe5ebd7 iOS H5 容器的一些探究(一):UIWebView 和 WKWebView 的比较和选择 一.前言 ...
- WPF 之 style文件的引用
总结一下WPF中Style样式的引用方法. 一.内联样式: 直接设置控件的Height.Width.Foreground.HorizontalAlignment.VerticalAlignment等属 ...
- 二手奢侈品电商Vestiaire Collective融资2000万美元
巴黎奢侈品电商Vestiaire Collective获得了2000万美元的C轮融资,投资方包括知名出版集团Condé Nast.Idinvest.Balderton和Ventech,其中Condé ...
- [JavaEE] applicationContext.xml配置文件使用合集
配置实例 – 1 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http ...
- 最近在用placeholder ,是已有的,网上也有不少都是jq写的
其实除了支持placeholder 的浏览器,其他用js 或jq实现的都不叫placeholder 效果,只能算上是获取焦点,或失去焦点时的一个placeholder 没有出生时就已经存在效果 很多人 ...
- [经典算法] 排列组合-N元素集合的M元素子集
题目说明: 假设有个集合拥有n个元素,任意的从集合中取出m个元素,则这m个元素所形成的可能子集有那些? 题目解析: 假设有5个元素的集合,取出3个元素的可能子集如下: {1 2 3}.{1 2 4 } ...