C++中const使用注意要点(一)

最近看《C++编程思想》发现自己的基础确实不牢固,也想起了以前写代码时也因为const的事情浪费过时间,这里总结下几个要点。

首先说下内部链接和外部链接。

当一个cpp文件在编译时,预处理器首先递归包含头文件,形成一个含有所有必要信息的单个源文件,这个源文件就是一个编译单元。编译器对每个编译单元(.cpp文件)进行编译生成相应.obj文件。PS:.c文件对应.o文件

接下来关键一步:链接器将所有不相关的.obj文件进行链接,生成最终可执行文件(.exe文件)

// a.cpp:
#include "stdafx.h"
void show();

int main()
{
	show();
	return 0;
}
// b.cpp
#include "stdafx.h"
#include <iostream>
void show()
{
	std::cout << "Hello World" << std::endl;
}

看上述代码,函数的声明和定义可以在不同的cpp文件中,并且声明可以有很多个,定义只能有一个

在某个编译单元中调用show函数,那么必须进行声明。来看下外部链接和内部链接的定义:

外部链接:一个名称对编译单元来说不是局部的,链接的时候其他编译单元可以访问它。

内部链接:一个名词对编译单元来说是局部的,链接的时候其他编译单元无法链接到它且不会与其他编译单元的同样称冲突。

可以看出,show函数是外部链接,a.cpp中的void show();等价于extern void show();

而static和全局的变量或函数都是外部链接,而由于函数的声明跟定义明显有区别(一个后接分号一个后接大括号),所以不用特地加extern区分。

回到主题,C++的const默认是内部链接的!也就是说const仅在const被定义过的文件里才是可见的。除非用extern进行声明,才会使用外部链接。

默认内部链接时,C++编译器不会给const创建存储空间,而是把它的定义放在符号表中。这称之为常量折叠,起到了跟#宏一样的效果。当然,在运行时还是会创建的,见下述例子。

#include <iostream>

int main()
{
	const int i = 10;
	int* p = const_cast<int*>(&i);
	*p = 8;

	std::cout << *p << " " << i << std::endl;

	return 0;
}

结果是8 10

说明运行时可以取得const常量的地址,并且可以改变存放的值。但是对于const常量来说,实际只是从符号表中查找值。因此虽然内容发生了变化,但是i输出还是10。

再来看看const的常见用法(下面的int均可换成其他基本数据类型或类名)

1、和指针一起使用

const int*或int const *——不能通过指针改变int的值,但是指针指向的地址可以改变,一般使用前者

int* const——不能改变指针指向的地址,但是可以通过指针改变int的值

const int* const或int const* const——不能通过指针改变int的值,也不能改变指针指向的地址

2、一般要把const int*转换成int*需要强制转换,而字符数组是没有强调const特性的,见下面代码

#include <iostream>

int main()
{
	char* pc = "hello world!";
	std::cout << pc << std::endl;  // 可以输出
	pc[2] = ‘s‘;  // 运行时错误!
	return 0;
}

编译通过,也能输出hello world!,但是运行时出错。这里"hello world!"被编译器当作常量字符数组建立的,所以得到的只是数组在内存里的首地址,对字符数组内任何字符进行修改会导致运行时错误。

要想修改字符串需要把它放在数组中,即把char* pc改成char pc[]

3、作为函数参数和返回值

作为参数:比如void f(const int i){}假如调用f(5);相当于在函数体中const int i = 5;然后再对i进行操作,所以不能修改i。

作为返回值:比如const int f(){ return 1; }假如调用int i = f();相当于const int tmp = f(); int i = tmp;所以没有任何意义,返回值进行值传递,还是能改变。

但是返回的是对象(假如是类A的对象)时,比如const A f(); 返回值不能作为左值!(左值右值以后再详述)

虽然A g();中g()的返回值可以作为左值,但是也只是临时对象,表达式被编译过后临时对象也会被清除

时间: 2024-10-08 20:03:21

C++中const使用注意要点(一)的相关文章

c++ 中const的使用

在c++中,const是这么一个东西:如果你希望能够有一些东西是别人不能修改的,这个时候const就起作用了. const 在使用情况如下: a.修饰常量 const int a; int const a; 这里不论const放什么位置,效果其实都一样的. b.修饰指针: const double *p--const放于指针*之前,代表当前指针指向的内存是不可改变的. double *const p--const放于指针*之后,代表当前指针是不可改变的. const double *const

C++中const限定符的应用

const限定符用于限定变量或对象的值.const对象一旦创建其值不能再改变.在C++中,const与引用和指针相结合,有多种用法.下面将结合<C++ Primer>第五版的内容做一个较详细的介绍. 1.const对象初始化 const对象必须初始化,初始化可以是任意复杂的表达式,如: const int i=get_size(); const int j=42; 2.文件间共享const对象 当以编译时初始化的方式定义一个const对象时,编译器将在编译过程中把用到该变量的地方都替换成对应的

c++中const关键字全面总结

一.const作用 1.const定义常量 注意:const只对它左边的东西起作用,唯一的例外就是const本身就是最左边的修饰符,那么它才会对右边的东西起作用. (1)const修饰变量,以下两种定义形式在本质上是一样的.它的含义是:const修饰的类型为TYPE的变量value是不可变的. TYPE const ValueName = value; const TYPE ValueName = value; (2)将const改为外部连接,作用于扩大至全局,编译时会分配内存,并且可以不进行初

C++ 中 const 和 static 的作用

目录 const 的主要应用如下: const 关键字使用的注意点: C++中static关键字有三个明显的作用: const的主要应用如下: const 用于定义常量:const定义的常量编译器可以对其进行数据静态类型的安全检查. const 修饰函数形式参数:当输入参数为用户自定义类型和抽象数据类型的时候,将"值传递"改为"const 引用传递" 可以提高效率. const 修饰函数的返回值:如果给"指针传递"的函数返回值加const,则返回

C++中const用法总结

1. const修饰普通变量和指针const修饰变量,一般有两种写法:const TYPE value;TYPE const value;这两种写法在本质上是一样的.它的含义是:const修饰的类型为TYPE的变量value是不可变的.对于一个非指针的类型TYPE,无论怎么写,都是一个含义,即value只不可变.例如:const int nValue:         //nValue是constint const nValue:    // nValue是const但是对于指针类型的TYPE,

C++中const简介

C++中的const关键字的用法非常灵活,而使用const将大大改善程序的健壮性,本人根据各方面查到的资料进行总结如下,期望对朋友们有所帮助. Const 是C++中常用的类型修饰符,常类型是指使用类型修饰符const说明的类型,常类型的变量或对象的值是不能被更新的. const关键字的作用主要有以下几点: (1)可以定义const常量,具有不可变性. 例如: const int Max=100; int Array[Max]; (2)便于进行类型检查,使编译器对处理内容有更多了解,消除了一些隐

结合示例说明C++中const和指针结合时怎么理解

在之前随笔<C++中const使用要点(一)>中简单叙述了const int*.int* const和const int* const的区别,记住三句话就能在实际运用时用对,但是看书时发现了指针常量.常量指针这些名词,发现明白这些概念对阅读文章时还是比较重要的. 关键:const和指针结合时代码从右往左看 1.常量指针(const pointer) 概念:常量是形容词,也就是说常量指针是一个指针,用const修饰的指针. 按照代码从右往左(概念名词从左往右)的阅读顺序,不妨试着写一下. Ste

C/C++中const的用法

const是C语言的关键字,经C++进行扩充,变得功能强大,用法复杂.const用于定义一个常变量(只读变量),当const与指针,引用,函数等结合起来使用时,情况会变得复杂的多.下面将从五个方面总结const的用法. 1.const位置 const位置较为灵活,一般来说,除了修饰一个类的成员函数外,const不会出现先一条语句的最后.示例如下: #include <iostream> using namespace std; int main(int argc,char* argv[]) {

C++中const char * const name;char * const name;cons

C++中const char * const name;char * const name;const char * name三者之间的区别? 著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处.作者:HG Zhao链接:http://www.zhihu.com/question/26908463/answer/34499495来源:知乎 const *说明指向的是常量.* const说明指针是常量.const * const说明指针和指向的都是常量.