const用法介绍.doc_第1页
const用法介绍.doc_第2页
const用法介绍.doc_第3页
const用法介绍.doc_第4页
const用法介绍.doc_第5页
已阅读5页,还剩20页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

const,extern,static,volatile的使用1Const 深度解析3const用法详解9const,extern,static,volatile的使用1. const的用法:为什么使用const?采用符号常量写出的代码更容易维护;指针常常是边读边移动,而不是边写边移动;许多函数参数是只读不写的。const最常见用途是作为数组的界和switch分情况标号(也可以用枚举符代替) 用法1:常量取代了C中的宏定义,声明时必须进行初始化。const限制了常量的使用方式,并没有描述常量应该如何分配。如果编译器知道了某const的所有使用,它甚至可以不为该const分配空间。最简单的常见情况就是常量的值在编译时已知,而且不需要分配存储。C+ Program Language用const声明的变量虽然增加了分配空间,但是可以保证类型安全。C标准中,const定义的常量是全局的,C+中视声明位置而定。用法2:指针和常量使用指针时涉及到两个对象:该指针本身和被它所指的对象。将一个指针的声明用const“预先固定”将使那个对象而不是使这个指针成为常量。要将指针本身而不是被指对象声明为常量,必须使用声明运算符*const。所以出现在 * 之前的const是作为基础类型的一部分:char *const cp; /到char的const指针char const *pc1; /到const char的指针const char *pc2; /到const char的指针(后两个声明是等同的)从右向左读的记忆方式:cp is a const pointer to char.pc2 is a pointer to const char.用法3:const修饰函数传入参数将函数传入参数声明为const,以指明使用这种参数仅仅是为了效率的原因,而不是想让调用函数能够修改对象的值。同理,将指针参数声明为const,函数将不修改由这个参数所指的对象。通常修饰指针参数和引用参数:void Fun( const A *in); /修饰指针型传入参数void Fun(const A &in); /修饰引用型传入参数用法4:修饰函数返回值可以阻止用户修改返回值。返回值也要相应的付给一个常量或常指针。用法5:const修饰成员函数const对象只能访问const成员函数,而非const对象可以访问任意的成员函数,包括const成员函数;const对象的成员是不能修改的,而通过指针维护的对象确实可以修改的;const成员函数不可以修改对象的数据,不管对象是否具有const性质。编译时以是否修改成员数据为依据进行检查。2.static的用法:静态变量作用范围在一个文件内,程序开始时分配空间,结束时释放空间,默认初始化为0,使用时可以改变其值。静态变量或静态函数只有本文件内的代码才能访问它,它的名字在其它文件中不可见。用法1:函数内部声明的static变量,可作为对象间的一种通信机制如果一局部变量被声明为static,那么将只有唯一的一个静态分配的对象,它被用于在该函数的所有调用中表示这个变量。这个对象将只在执行线程第一次到达它的定义使初始化。用法2:局部静态对象对于局部静态对象,构造函数是在控制线程第一次通过该对象的定义时调用。在程序结束时,局部静态对象的析构函数将按照他们被构造的相反顺序逐一调用,没有规定确切时间。用法3:静态成员和静态成员函数如 果一个变量是类的一部分,但却不是该类的各个对象的一部分,它就被成为是一个static静态成员。一个static成员只有唯一的一份副本,而不像常规 的非static成员那样在每个对象里各有一份副本。同理,一个需要访问类成员,而不需要针对特定对象去调用的函数,也被称为一个static成员函数。类的静态成员函数只能访问类的静态成员(变量或函数)。3.extern的用法:extern可以声明其他文件内定义的变量。在一个程序里,一个对象只能定义一次,它可以有多个声明,但类型必须完全一样。如果定义在全局作用域或者名字空间作用域里某一个变量没有初始化,它会被按照默认方式初始化。将变量或函数声明成外部链接,即该变量或函数名在其它函数中可见。被其修饰的变量(外部变量)是静态分配空间的,即程序开始时分配,结束时释放。在C+中,还可以指定使用另一语言链接,需要与特定的转换符一起使用。extern “C” 声明语句extern “C” 声明语句块 4.volatile的用法:类型修正符(type-modifier),限定一个对象可被外部进程(操作系统、硬件或并发进程等)改变。volatile与变量连用,可以让变量被不同的线程访问和修改。声明时语法:int volatile vInt;常用于像中断处理程序之类的异步进程进行内存单元访问。除了基本类型外,对用户定义类型也可以用volatile类型进行修饰。注意:可以把一个非volatile int赋给volatile int,但是不能把非volatile对象赋给一个volatile对象。一个有volatile标识符的类只能访问它接口的子集,一个由类的实现者控制的子集。用户只能用const_cast来获得对类型接口的完全访问。此外,volatile向const一样会从类传递到它的成员。Const 深度解析我们也许学习过const的使用,但是对于const的细致的技术细节却不一定掌握。const的用法在许多的教材上只是简单的介绍,在这里我们对 const进行细致的概念以及用法剖析。const 是由c+采用,并加进标准c中,但是他们的意义完全不同,在旧版本(标准前)的c中,如果想建立一个常量,必须使用预处理器:#define PI 3.14159此后无论在何处使用PI,都会被预处理器以3.14159替代。编译器不对PI进行类型检查,也就是说可以不受限制的建立宏并用它来替代值,如果使用不慎,很可能由预处理引入错误,这些错误往往很难发现。我们也不能得到PI的地址(即不能向PI传递指针和引用)。c+引入了命名常量的概念,命名常量就像变量一样,只是它的值不能改变,如果试图改变一个const 对象,编译器将会产生错误。 const 和正常变量一样有作用域,所以函数内部的const也不会影响程序的其余部分。在c+中const可以取代预处理器#define来进行值替代, const有安全的类型检查,所以不用担心会像预处理器一样引入错误。在通常的情况下const同预处理器#define一样只是将所赋值保存入编译器的符号表中(符号表仅仅在编译时存在,在编译过程中编译器将程序中的名字与之在符号表中定义的数值作简单的替换),在使用的时候进行值替换,并不为const创建存储空间。我们将const的定义放进头文件里,这样通过包含头文件,可以把const定义单独放在一个地方并把它分配给一个编译单元,const默认为内部连接(内部连接意味着只对正在编译的文件创建存储空间,别的文件可以使用相同的标示符和全局变量,编译器不会发现冲突,外部连接意味着为所有被编译过的文件创建一片单独的存储空间,一般全局变量和函数名的外部连接通过extern声明,可以通过其他的文件访问)也就是说const仅能被它所定义过的文件访问,在定义一个const时,必须赋一个值给它,除非用extern做出说明:extern const int a;这表示const的定义在其他的什么地方,这里仅仅是一个声明,但是这样的做法使const使用了外部连接,也就是说上面的extern强制进行了对const的存储空间分配,这样我们就无法再用const作为常量折叠(在可能的情况下,符号常量的值会代替改名字的出现,这个替代过程叫做常量折叠)使用了,即使我们在其他地方定义了const的值,如:extern const int a=3;因为const的值被放入了存储单元,在编译的过程中,编译器不会去读存储单元的内容。如果我们这样做:int ba;编译器就会给我们一个错误信息。想不为const分配存储空间是不可能的,因为对于复杂的结构,例如集合,编译器不会复杂到将集合保存到它的符号表中,所以必须分配内存空间,这就意味着“这是一块不能改变的存储空间”,当然也就不能在编译期间使用它的值,因为编译器不知道存储的内容:const int i=1,2,3,4;/float fi2; /将得到错误信息,编译器提示不能在数组定义里找到一个常数表达式。因为编译器靠移动栈指针来存储和读取数据。也因此,由于无法避免为const分配内存,所以const的定义必须默认为内部连接,否则由于众多的const在多个文件中分配内存,就会引起错误。下面我们看一段简单有效的代码来说明const的常量折叠:#include const int a=3;const int b=a+1;float *f=(float*)&b;char cb+3;void main()const char gc=cin.get();const char c2=gc+3;我们可以看到,a是一个编译器期间的const,b是从a中计算出来的,由于a是一个const,b的计算值来自一个常数表达式,而它自身也是一个编译器间的const,接着下面指针f取得了b的地址,所以迫使编译器给b分配了存储空间,不过即使分配了存储空间,由于编译器已经知道了b的值,所以仍然不妨碍在决定数组c的大小时使用b。在主函数main()里,标识符gc的值在编译期间是不知道的,这也意味着需要存储空间,但是初始化要在定义点进行,而且一旦初始化,其值就不能改变,我们发现c2是由gc计算出来的,它的作用域与其他类型const的作用域是一样的,这是对#define用法的一种改进。在c+引进常量的时候,标准c也引入了const,但是在c中const的意思和在c+中有很大不同,在c中const的意思是“一个不能改变的普通变量”,const常量总是被分配存储空间而且它的名字是全局符即const使用外部连接。于是在c中:const int size=100;char csize;得出一个错误。但是在c中可以这样写:const int size;因为c中的const被默认为外部连接,所以这样做是合理的。在c语言中使用限定符const不是很有用,如果希望在常数表达式里(必须在编译期间被求值)使用一个已命名的值,必须使用预处理器#define。在c+中可以使指针成为const,这很有用,如果以后想在程序代码中改变const这种指针的使用,编译器将给出通知,这样大大提高了安全性。在用带有const的指针时,我们有两种选择:const修饰指针指向的对象,或者const修饰指针自己指向的存储空间。如果要使指向的对象不发生改变,则需要这样写:const int *p;这里p是一个指向const int 的指针,它不需要初始化,因为p可以指向任何标识符,它自己并不是一个const,但是它所指的值是不能改变的,同样的,我们可以这样写:int const *p;这两种方法是等同的,依据个人习惯以及编码风格不同,程序员自己决定使用哪一种形式。如果希望使指针成为一个const必须将const标明的部分放在*右边。int a=3;int *const j=&a编译器要求给它一个初始值,这个值在指针的生命期间内不变,也就是说指针始终指向a的地址,不过要改变它地址中的值是可以的:*j+=4;也可以是一个const指针指向一个const对象:const int *j1=&a;int const *j2=&a;这样指针和对象都不能改变,这两种形式同样是等同的。在赋值的的时候需要注意,我们可以将一个非const的对象地址赋给一个const指针,但是不能将一个const对象地址赋给一个非const指针,因为这样可能通过被赋值的指针改变对象的值,当然也可以用类型的强制转换来进行const对象的赋值,但是这样做打破了const提供的安全性。const也被用于限定函数参数和函数的返回值,如果函数参数是按值传递时,即表示变量的初值不会被函数改变,如果函数的返回值为const那么对于内部类型来说按值返回的是否是一个cosnt是无关紧要的,编译器不让它成为一个左值,因为它是一个值而不是一个变量,所以使用const是多余的,例如:const int f()return 1;void main()int a=f();但是当处理用户定义类型的时候,按值返回常量就很有意义了,这时候函数的返回值不能被直接赋值也不能被修改。仅仅是非const返回值能作为一个左值使用,但是这往往失去意义,因为函数返回值在使用时通常保存为一个临时量,临时量被作为左值使用并修改后,编译器将临时量清除。结果丢失了所有的修改。可以用const限定传递或返回一个地址(即一个指针或一个引用):const int * const func(const int *p) static int a=*p;return &a;参数内的const限定指针p指向的数据不能被改变,此后p的值被赋给静态变量a,然后将a的地址返回,这里a是一个静态变量,在函数运行结束后,它的生命期并没有结束,所以可以将它的地址返回。因为函数返回一个const int* 型,所以函数func的返回值不可以赋给一个非指向const的指针,但它同时接受一个const int * const和一个const int *指针,这是因为在函数返回时产生一个const临时指针用以存放a的地址,所以自动产生了这种原始变量不能被改变的约定,于是*右边的const只有当作左值使用时才有意义。const同样运用于类中,但是它的意义又有所不同,我们可以创建const的数据成员,const的成员函数,甚至是const的对象,但是保持类的对象为const比较复杂,所以const对象只能调用const成员函数。const的数据成员在类的每一个对象中分配存储,并且一旦初始化这个值在对象的生命期内是一个常量,因此在类中建立一个const数据成员时,初始化工作必须在构造函数初始化列表中。如果我们希望创建一个有编译期间的常量成员,这就需要在该常量成员的前面使用static限定符,这样所有的对象都仅有一个实例:class Xstatic const int size=50;int asize;public:X();const对象只能调用const成员函数,一个普通对象同样可以调用const成员函数,因此,const成员函数更具有一般性,但是成员函数不会默认为const。声明一个const成员函数,需要将const限定符放在函数名的后面:void f (void ) const;当我们运用const成员函数时,遇到需要改变数据成员,可以用mutable进行特别的指定:class Xmutable int i;public:X();void nochange() const;void X:nochange const()i+;const消除了预处理器的值替代的不良影响,并且提供了良好的类型检查形式和安全性,在可能的地方尽可能的使用const对我们的编程有很大的帮助。const用法详解面向对象是C+的重要特性. 但是c+在c的基础上新增加的几点优化也是很耀眼的就const直接可以取代c中的#define以下几点很重要,学不好后果也也很严重const1. 限定符声明变量只能被读 const int i=5; int j=0; . i=j; /非法,导致编译错误 j=i; /合法2. 必须初始化 const int i=5; /合法 const int j; /非法,导致编译错误3. 在另一连接文件中引用const常量 extern const int i; /合法 extern const int j=10; /非法,常量不可以被再次赋值4. 便于进行类型检查 用const方法可以使编译器对处理内容有更多了解。 #define I=10 const long &i=10; /*dapingguo提醒:由于编译器的优化,使 得在const long i=10; 时i不被分配内存,而是已10直接代入 以后的引用中,以致在以后的代码中没有错误,为达到说教效 果,特别地用&i明确地给出了i的内存分配。不过一旦你关闭所 有优化措施,即使const long i=10;也会引起后面的编译错误。*/ char h=I; /没有错 char h=i; /编译警告,可能由于数的截短带来错误赋值。5. 可以避免不必要的内存分配 #define STRING abcdefghijklmnn const char string=abcdefghijklmn; . printf(STRING); /为STRING分配了第一次内存 printf(string); /为string一次分配了内存,以后不再分配 . printf(STRING); /为STRING分配了第二次内存 printf(string); . 由于const定义常量从汇编的角度来看,只是给出了对应的内存地址, 而不是象#define一样给出的是立即数,所以,const定义的常量在 程序运行过程中只有一份拷贝,而#define定义的常量在内存中有 若干个拷贝。6. 可以通过函数对常量进行初始化 int value(); const int i=value(); dapingguo说:假定对ROM编写程序时,由于目标代码的不可改写, 本语句将会无效,不过可以变通一下: const int &i=value(); 只要令i的地址处于ROM之外,即可实现:i通过函数初始化,而其 值有不会被修改。7. 是不是const的常量值一定不可以被修改呢? 观察以下一段代码: const int i=0; int *p=(int*)&i; p=100; 通过强制类型转换,将地址赋给变量,再作修改即可以改变const常量值。8. 请分清数值常量和指针常量,以下声明颇为玩味: int ii=0; const int i=0; /i是常量,i的值不会被修改 const int *p1i=&i; /指针p1i所指内容是常量,可以不初始化 int * const p2i=ⅈ /指针p2i是常量,所指内容可修改 const int * const p3i=&i; /指针p3i是常量,所指内容也是常量 p1i=ⅈ /合法 *p2i=100; /合法 关于C+中的const关键字的用法非常灵活,而使用const将大大改善程序的健壮性,参考了康建东兄的const使用详解一文,对其中进行了一些补充,写下了本文。1. const常量,如const int max = 100; 优点:const常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查,而对后者只进行字符替换,没有类型安全检查,并且在字符替换时可能会产生意料不到的错误(边际效应)2. const 修饰类的数据成员。如:class A const int size; const数据成员只在某个对象生存期内是常量,而对于整个类而言却是可变的。因为类可以创建多个对象,不同的对象其const数据成员的值可以不同。所以不能在类声明中初始化const数据成员,因为类的对象未被创建时,编译器不知道const 数据成员的值是什么。如class Aconst int size = 100; /错误int arraysize; /错误,未知的sizeconst数据成员的初始化只能在类的构造函数的初始化表中进行。要想建立在整个类中都恒定的常量,应该用类中的枚举常量来实现。如class Aenum size1=100, size2 = 200 ;int array1size1;int array2size2; 枚举常量不会占用对象的存储空间,他们在编译时被全部求值。但是枚举常量的隐含数据类型是整数,其最大值有限,且不能表示浮点数。3. const修饰指针的情况,见下式:int b = 500; const int* a = & 1 int const *a = & 2 int* const a = & 3 const int* const a = & 4 如果你能区分出上述四种情况,那么,恭喜你,你已经迈出了可喜的一步。不知道,也没关系,我们可以参考Effective c+Item21上的做法,如果const位于星号的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量;如果const位于星号的右侧,const就是修饰指针本身,即指针本身是常量。因此,1和2的情况相同,都是指针所指向的内容为常量(const放在变量声明符的位置无关),这种情况下不允许对内容进行更改操作,如不能*a = 3 ;3为指针本身是常量,而指针所指向的内容不是常量,这种情况下不能对指针本身进行更改操作,如a+是错误的;4为指针本身和指向的内容均为常量。 4. const的初始化 先看一下const变量初始化的情况 1) 非指针const常量初始化的情况:A b; const A a = b; 2) 指针const常量初始化的情况:A* d = new A(); const A* c = d; 或者:const A* c = new A(); 3)引用const常量初始化的情况: A f; const A& e = f; / 这样作e只能访问声明为const的函数,而不能访问一 般的成员函数; 思考1: 以下的这种赋值方法正确吗? const A* c=new A(); A* e = c; 思考2: 以下的这种赋值方法正确吗? A* const c = new A(); A* b = c;5. 另外const 的一些强大的功能在于它在函数声明中的应用。在一个函数声明中,const 可以修饰函数的返回值,或某个参数;对于成员函数,还可以修饰是整个函数。有如下几种情况,以下会逐渐的说明用法:A& operator=(const A& a); void fun0(const A* a ); void fun1( ) const; / fun1( ) 为类成员函数 const A fun2( );1) 修饰参数的const,如 void fun0(const A* a ); void fun1(const A& a); 调用函数的时候,用相应的变量初始化const常量,则在函数体中,按照const所修饰的部分进行常量化,如形参为const A* a,则不能对传递进来的指针的内容进行改变,保护了原指针所指向的内容;如形参为const A& a,则不能对传递进来的引用对象进行改变,保护了原对象的属性。 注意:参数const通常用于参数为指针或引用的情况,且只能修饰输入参数;若输入参数采用“值传递”方式,由于函数将自动产生临时变量用于复制该参数,该参数本就不需要保护,所以不用const修饰。总结对于非内部数据类型的输入参数,因该将“值传递”的方式改为“const引用传递”,目的是为了提高效率。例如,将void Func(A a)改为void Func(const A &a) 对于内部数据类型的输入参数,不要将“值传递”的方式改为“const引用传递”。否则既达不到提高效率的目的,又降低了函数的可理解性。例如void Func(int x)不应该改为void Func(const int &x)2) 修饰返回值的const,如const A fun2( ); const A* fun3( ); 这样声明了返回值后,const按照修饰原则进行修饰,起到相应的保护作用。const Rational operator*(const Rational& lhs, const Rational& rhs) return Rational(lhs.numerator() * rhs.numerator(), lhs.denominator() * rhs.denominator(); 返回值用const修饰可以防止允许这样的操作发生:Rational a,b; Radional c; (a*b) = c; 一般用const修饰返回值为对象本身(非引用和指针)的情况多用于二目操作符重载函数并产生新对象的时候。 总结1. 一般情况下,函数的返回值为某个对象时,如果将其声明为const时,多用于操作符的重载。通常,不建议用const修饰函数的返回值类型为某个对象或对某个对象引用的情况。原因如下:如果返回值为某个对象为const(const A test = A 实例)或某个对象的引用为const(const A& test = A实例) ,则返回值具有const属性,则返回实例只能访问类A中的公有(保护)数据成员和const成员函数,并且不允许对其进行赋值操作,这在一般情况下很少用到。 2. 如果给采用“指针传递”方式的函数返回值加const修饰,那么函数返回值(即指针)的内容不能被修改,该返回值只能被赋给加const 修饰的同类型指针。如:const char * GetString(void);如下语句将出现编译错误:char *str=GetString();正确的用法是:const char *str=GetString();3. 函数返回值采用“引用传递”的场合不多,这种方式一般只出现在类的赙值函数中,目的是为了实现链式表达。如:class AA &operate = (const A &other); /负值函数A a,b,c; /a,b,c为A的对象a=b=c; /正常(a=b)=c; /不正常,但是合法若负值函数的返回值加const修饰,那么该返回值的内容不允许修改,上例中a=b=c依然正确。(a=b)=c就不正确了。思考3: 这样定义赋值操作符重载函数可以吗? const A& operator=(const A& a);6. 类成员函数中const的使用 一般放在函数体后,形如:void fun() const; 任何不会修改数据成员的函数都因该声明为const类型。如果在编写const成员函数时,不慎修改了数据成员,或者调用了其他非const成员函数,编译器将报错,这大大提高了程序的健壮性。如:class Stackpublic: void Push(int elem); int Pop(void); int GetCount(void) const; /const 成员函数private: int m_num; int m_data100;int Stack:GetCount(void) const +m_num; /编译错误,企图修改数据成员m_num Pop(); /编译错误,企图调用非const函数 Return m_num;7. 使用const的一些建议 1 要大胆的使用const,这将给你带来无尽的益处,但前提是你必须搞清楚原委; 2 要避免最一般的赋值操作错误,如将const变量赋值,具体可见思考题; 3 在参数中使用const应该使用引用或指针,而不是一般的对象实例,原因同上; 4 const在成员函数中的三种用法(参数、返回值、函数)要很好的使用; 5 不要轻易的将函数的返回值类型定为const; 6除了重载操作符外一般不要将返回值类型定为对某个对象的const引用; 思考题答案 1 这种方法不正确,因为声明指针的目的是为了对其指向的内容进行改变,而声明的指针e指向的是一个常量,所以不正确; 2 这种方法正确,因为声明指针所指向的内容可变; 3 这种做法不正确; 在const A:operator=(const A& a)中,参数列表中的const的用法正确,而当这样连续赋值的时侯,问题就出现了: A a,b,c: (a=b)=c; 因为a.operator=(b)的返回值是对a的const引用,不能再将c赋值给const常量。const类型定义:指明变量或对象的值是不能被更新,引入目的是为了取代预编译指令*常量必须被初始化*cons的作用(1)可以定义const常量例如:constintMax=100;intArrayMax;(2)便于进行类型检查例如:voidf(constinti).编译器就会知道i是一个常量,不允许修改;(3)可以保护被修饰的东西,防止意外的修改,增强程序的健壮性。还是上面的例子,如果在函数体内修改了i,编译器就会报错;例如:voidf(constinti)i=10;/error!(5)为函数重载提供了一个参考。classA.voidf(inti).file:/一个函数voidf(inti)const.file:/上一个函数的重载.;(6)可以节省空间,避免不必要的内存分配。例如:#definePI3.14159file:/常量宏constdoulbePi=3.14159;file:/此时并未将Pi放入ROM中.doublei=Pi;file:/此时为Pi分配内存,以后不再分配!doubleI=PI;file:/编译期间进行宏替换,分配内存doublej=Pi;file:/没有内存分配doubleJ=PI;file:/再进行宏替换,又一次分配内存!const定义常量从汇编的角度来看,只是给出了对应的内存地址,而不是象#define一样给出的是立即数,所以,const定义的常量在程序运行过程中只有一份拷贝,而#define定义的常量在内存中有若干个拷贝。(7)提高了效率。编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。使用const(1)修饰一般常量,常数组,常对象修饰符const可以用在类型说明符前,也可以用在类型说明符后。例如:intconstx=2;或constintx=2;intconsta5=1,2,3,4,5;或constinta5=1,2,3,4,5;classA;constAa;或Aconsta;(2)修饰指针constint*A;或intconst*A;/const修饰指向的对象,A可变,A指向的对象不可变int*constA;/const修饰指针A,A不可变,A指向的对象可变constint*constA;/指针A和A指向的对象都不可变(3)修饰引用constdouble&v;该引用所引用的对象不能被更新(4)修饰函数的返回值:const修饰符也可以修饰函数的返回值,是返回值不可被改变,格式如下:constintFun1();constMyClassFun2();(5)修饰类的成员函数:const修饰符也可以修饰类的成员函数,格式如下:classClassNamepublic:intFun()const;.;这样,在调用函数Fun时就不能修改类里面的数据(6)在另一连接文件中引用const常量externconstinti;/正确的引用externconstintj=10;/错误!常量不可以被再次赋值*放在类内部的常量有什么限制?classAprivate:constintc3=7;/errstaticintc4=7;/errstaticconstfloatc5=7;/err.;初始化类内部的常量1初始化列表:classApublic:A(inti=0):test(i)private:constinti;;2外部初始化,例如:classApublic:A()private:staticconstinti;;constintA:i=3;C+ const 用法总结#include void func(const int* p, int n);const char * getStr();class CAprivate:int _nA;public:CA(int a):_nA(a)inline int getA() const /_nA+; /error C2166: l 值指定常数对象 return _nA;inline void setA(int a) _nA = a;int main(void)using namespace std;/=/ 1.const修饰变量使其成为常量/= cout-const修饰变量使其成为常量:endl; const

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论