首页 技术 正文
技术 2022年11月23日
0 收藏 739 点赞 5,109 浏览 2387 个字

Const 的使用读书笔记

Const的主要主要用法有:

常变量: const 类型说明符 变量名

常引用: const 类型说明符 &引用名 
常对象: 类名 const 对象名
常成员函数: 类名::fun(形参) const
常数组: 类型说明符 const 数组名[大小]
常指针: const 类型说明符* 指针名 ,类型说明符* const 指针名

  • 常变量

      例如:const int a;  或  int const a; 在c语言中声明时必须进行初始化,C++中则没有这个限制。C 标准中,const 定义的常量是全局的,C++中视声明位置而定。

  • 指针常量和常量指针

    const int *x; 指向常整型的指针,x所指向的数据不能被修改

    int *const x; 指向整形的常量指针,x不能指向其它地址;

    const int *const x;指向常整型的常量指针,x所指向的数据不能被修改,同时x自身也不能指向其他地址空间。

    对于const int *x,虽然不能直接修改*x的值,但是我们可以通过下面的方式来修改:

int i = ;const int *x = &i;    int *p = (int *)x;    *p = ;    //此时i=11; *x= 11;

  同样在函数参数中使用指针常量和常量指针的意义是一样的。   Void f(const char *p);  void f(char *const p);

  如果参数作输出用,不论它是什么数据类型,也不论它采用“指针传递”还是“引用传递”,都不能加const 修饰,否则该参数将失去输出功能。const 只能修饰输入参数:如果输入参数采用“指针传递”,那么加const 修饰可以防止意外地改动该指针,起到保护作用。例如StringCopy 函数:

void StringCopy(char *strDestination, const char *strSource);

其中strSource 是输入参数,strDestination 是输出参数。给strSource 加上const修饰后,如果函数体内的语句试图改动strSource 的内容,编译器将指出错误。

  如果输入参数采用“值传递”,由于函数将自动产生临时变量用于复制该参数,该输入参数本来就无需保护,所以不要加const 修饰。例如不要将函数void Func1(int x) 写成void Func1(const int x)。同理不要将函数void Func2(A a) 写成void Func2(const A a)。其中A 为用户自定义的数据类型。

  对于非内部数据类型的参数而言,象void Func(A a) 这样声明的函数注定效率比较底。因为函数体内将产生A 类型的临时对象用于复制参数a,而临时对象的构造、复制、析构过程都将消耗时间。

为了提高效率,可以将函数声明改为void Func(A &a),因为“引用传递”仅借用一下参数的别名而已,不需要产生临时对象。但是函数void Func(A &a) 存在一个缺点:

    “引用传递”有可能改变参数a,这是我们不期望的。解决这个问题很容易,加const修饰即可,因此函数最终成为void Func(const A &a)。以此类推,是否应将void Func(int x) 改写为void Func(const int &x),以便提高效率?完全没有必要,因为内部数据类型的参数不存在构造、析构的过程,而复制也非常快,“值传递”和“引用传递”的效率几乎相当。

  • 常量引用
    引用(reference)就是对象的另一个名字,引用主要用作函数的形式参数。常量引用表示不能通过改引用去修改对应内存的内容。
int i = ;const int &j = i;  //不能通过j改变i的值void func(const int& i)
{
i = ; // 错误!不能通过i 去改变它所代表的内存区域。
}
  • 常量函数

  在一个函数的签名后面加上关键字const 后该函数就成了常量函数。对于常量函数,最关键的不同是编译器不允许其修改类的数据成员

class Test
{
public:
void func() const;
private:
int intValue;
};
void Test::func() const
{
intValue = ;
}

  上面的代码中,常量函数func 函数内试图去改变数据成员intValue的值,因此将在编译的时候引发异常。

  • 常量对象
    如果我们把一个类定义为常量,我们的本意是希望他的状态(数据成员)不会被改变。那么,如果一个常量的对象调用它的非常量函数会产生什么后果呢?常量对象的状态不允许被修改,又因为非常了得函数可以修改类的成员,因此,通过常量对象调用非常量函数时将会产生语法错误。
  • 常量返回值
    这里就不总结了,具体的可以去看参考文档。

Const 常量定义相对于define宏定义的优势

const定义的常量具有数据类型,定义数据类型的常量便于编译器进行数据检查,使程序可能出现错误进行排查。define进行宏定义的时候,不会分配内存空间,编译时会在main函数里进行替换,只是单纯的替换,不会进行任何检查,比如类型,语句结构等,即宏定义常量只是纯粹的置换关系。

参考资料:

[1] http://www.phpweblog.net/maple094/archive/2008/05/30/4054.aspx

[2] http://social.msdn.microsoft.com/Forums/vstudio/zh-CN/b882d9d0-cd67-4eca-930c-7061133c50e6/faq225-const-int-int-const-const-int-const

[3] http://blog.csdn.net/ego51up_liyanhong/article/details/8624811

[4]http://www.360doc.com/content/11/0901/11/255982_144947210.shtml#

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:8,884
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,411
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,230
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,042
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,673
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,709