小白 有关c++ const的一点总结
2015-04-22 20:34
176 查看
本人学习程序设计已经快有一年之久,c++也有一个多月了,一直觉得c++中的const很令人蛋疼,于是在写程序时就有意的去避免const的使用,近期在写课程设计时却经常出现关于const的bug,于是就逛论坛决心弄懂const,论坛里说的很乱,于是自己做了一点点总结,本人小白,下面的东西仅供参考!有错,欢迎指出。本人使用vc 6.0编译器
一.const的用法
首先来看下面的几个例子
Const char* a
Char const* a
Char *const a
Typedef char*pchar const pchar a
如果都能很准确的说出指针的const类型说明你已经很厉害啦
下面给出解释
第一、二个指针相同,a是一个指向const对象的指针,其所指的对象为const的类型 ,意思是不能通过*a对元素的指进行修改,但可以用非const对象对指针进行赋值,指针所指向的元素也可以修改。第三个,a为const指针,其所指向的不能更改,在一开始定义时必须为其赋值,其所指向的对象的值可以修改,思考一下第四个是const与typedef的结合使用,是不是感觉它和第一二个很像,那你错了不能把typedef简单的当做文本拓展,其实它和第三个是一样的a为const指针。
二.const的赋值问题
1.元素赋值
定义const常量,必须在定义时就为该常量赋值,一个简单的例子(使用常量为const赋值)
Const int i//error
Const int i=5//ok
其实const不能称为常量,因为const的值是可以变化的,看下面的例子,
For(int j=1;j<5;j++)
Const int i=j;//ok
我也不明白从程序为什么可以运行,但是这就意味着我们可以用一个变量去初始化const常量,通过改变变量的值去修改 const的值,这种程序还是不用的好,因为这样就违反了const存在的初衷 但是i同样符合const的特性,一切视图使用变量名i去修改i的值的行为都会导致编译器报错 例如i=5//error 当然也可以使用const常量去初始化一个变量的值
其实这个涉及一个赋值时的对象复制问题,其实想想也是合理的,就不去深究啦!记住就好
2.指针引用赋值
Const最常用到的地方应该是指针和引用,指针和引用也存在不一样的地方,因为指针分为const指针和指向const对象的指针,而引用也就只用指向const对象的引用
首先说两者不一样的 const指针指的是const类型的指针,其指向不能改变,需要定义时赋值,一开始指向谁就以后就一直指向谁不能改变,可是其所指的对象的值却可以改变。例如
Const int* iptr//error
Const int*iptr=&a//ok;
*iptr=5;//ok
iptr=&b//error
而指向const类型对象的指针,其所指向可以改变,却不可以通过*iptr对对象的值进行改变,在定义时不必向上面那样对其赋值 可以在需要使用的时候在对它赋值。举个例子
Const int*iptr//ok;
iptr=&a;//ok
iptr=&b;//ok
*iptr=5//error;
也就是*iptr不能用作左值
有关引用就比指针更严格,定义const引用时,必须对该引用赋值,并且其引用的对象不能改变,这个没什么说的,可是在函数中const引用却用的最多
3.用const对象赋值其他类型的对象
说了那么多都在说对const对象的赋值,上面总结成一句话 const所定义的对象,除了在定义时,其他任何地方都不能用作左值(不知道对不对。。。)
下面说说用const对象赋值其他类型
首先用const对象赋值给const对象肯定是没问题的,当然如果是元素赋值,可以将const对象赋值给非const成员,涉及对象赋值,很好理解 如:
int j;
Const int i=5;
j=i;//ok;
而关于指向const对象的指针 这种指针只能赋值给相同类型的指针必须也为const ,与引用相同,不能将const类型的指针和引用赋值给非const类型的指针和引用。此处关于函数参数传递的问题,也就是因为这个我才开始了解const的。
还有const指针,,不说了,头有点晕,真的很绕人,说错了被打就不好了。。可能我理解的方法有问题。。Const指针可以赋值给非const指针,非const指针也可以赋值给const指针(仅限于初始化const指针的时候)。和元素赋值是一样的。
三.Const在函数中的应用
1.const用在函数前面,如
const int f1(void)
Const A f2(void)
Const A& f3(A&)
Const int*f4(void)
意思是函数的返回值是const,而第一种并不常见,因为系统定义的数据类型int本身返回的就是一个值,不可能是一个变量,用const修饰就没有意义。但是第二种,第三种返回值为const对象就可以避免下面的情况出现
f2()=A2;总是感觉出现这种的可能性不大,但是系统中很多这样的例子,比如a*b只能用作右值,当出现a*b=5时就会报错。
返回值虽然是const,但是仍然可以将返回值赋值给非const对象,当然第三个不可以赋值给非const的引用,却可以赋值给非const对象
例如
A a;
A&b;
a=f2()//ok
a=f3()//ok const引用可以赋值给非const对象(赋值是发生复制操作)
b=f3()//error const引用不能赋值给非const引用
对于第四个函数,返回值为一个指向const类型的指针,由于不能将const类型的指针和引用赋值给非const类型的指针和引用。故左值必须是指向const类型的指针,却又可以把const指针指向的值赋值给非const对象,故有下面的例子
Const int*a//ok
int *b;
Int c;
a=f4()//ok;
b=f4()//error 指向const对象的指针不能赋值给普通指针
c=*f4()//ok const对象可以赋值给非const对象(元素赋值问题)
PS:到目前为止我们很少使用过返回值为引用的函数,更如此很少将函数的返回值定义为const,因为返回的引用所指向的变量必须是全局变量,或者是主函数中使用的,我们可以将赋值=的重载定义为返回值为引用的函数,函数的返回值定义为const的情形多数在重载赋值操作符时出现!!!不到万不得以最好不要使用。
如 A& operator=(const A&a){};可以链式赋值
A a,b,c;
a=b=c;//ok
(a=b)=c//ok 但是不符合链式赋值的标准
此时就可以在函数前面加个const 这样第二种就不合法了。
2.const用在函数形参列表中
const所修饰的形参不可以改变,多数用于引用和指针的时候,为了保证传入的参数不被改变,
例如
Void f1(const int i)
Void f2(const int& i)
Void f3 (const int *i)
对于第一种存在的意义不大,因为本来的i就是传入参数的拷贝,传入参数本来就是安全的,所以不需要const,而第二种第三种就保护了传入的参数不发生改变。
PS:在定义类的成员函数的时候,对于不需要传入的参数发生改变时,一般都在形参前面加一个const,比如重载流操作符,重载关系运算符,默认构造函数。。。
3.Const用在函数体后(类的成员函数)
这种形式一般出现在类的成员函数中,目的是保护类的属性不会发生改变,在函数体内只能调用使用const在后修饰过得函数,一切可能会改变类的属性的函数都不能出现在该函数体内。一般只要在函数内不改变该类的属性的时候,都需要在函数后假如const,增加程序的健壮性
PS:当定义一个对象为const的时候,只能调用该对象的const用在函数体后的函数,
如const A a;
a只能调用此类函数,一切没有用const在后修饰的函数都不能调用
四.下面总结一下赋值问题
Const 对象 非const对象
Const引用 非const引用
Const指针 非const指针
指向const对象的指针 普通指针
“ ”指的是可以赋值
Const在初始化时,对初始化他的值可以是const类型,也可以是非const类型,但是在使用const常量为其他对象的指针和引用赋值时存在限制。
写这篇随笔的初衷:
一开始的我是不愿意涉及const的总觉得他的存在没有那么多的意义,在做程序设计时类的复制构造函数,以及重载等于操作符并没有使用const修饰形参,于是在将类放入vector中时,使用vector容器的push_back时出现了问题
下面贴出push_backde 源码
void push_back(const _Ty& _X)
{insert(end(), _X); }
下面是我遇到的问题:
Vector<R>Rs
Rs.push_back(R);
由于类中定义的复制构造函数传入参数为非const所以会报错
因为参数的传递大概是这样的:
非const对象 const引用 非const引用
后面的传递是传不过来的。
再瞎侃一下:
const有人说在c++中,与c中不相同已经归为常量,但是const与常量该是有很大的不同,毕竟我们可以把一个变量的值赋值给const,通过修改变量的值去修改此const常量的值。
在c++中我们可以定义一个const常量去作为数组的维数,如
Const int n=5;
Int a
;//ok
在c中是不可以的,数组的维数只能使用常量去定义,故此时的const可以认为就是常量
但是如果赋值时是变量 如:
Int j=5;
Const int i=j;//ok
Int a[i]//error C2057: expected constant expression
error C2466: cannot allocate an array of constant size 0
error C2133: 'a' : unknown size
所以在我看啊 const是否为常量应该由其初始化时的值所决定!(仅个人观点)
Const是c++中比较晦涩的部分,看了好久也只略懂一二。
一.const的用法
首先来看下面的几个例子
Const char* a
Char const* a
Char *const a
Typedef char*pchar const pchar a
如果都能很准确的说出指针的const类型说明你已经很厉害啦
下面给出解释
第一、二个指针相同,a是一个指向const对象的指针,其所指的对象为const的类型 ,意思是不能通过*a对元素的指进行修改,但可以用非const对象对指针进行赋值,指针所指向的元素也可以修改。第三个,a为const指针,其所指向的不能更改,在一开始定义时必须为其赋值,其所指向的对象的值可以修改,思考一下第四个是const与typedef的结合使用,是不是感觉它和第一二个很像,那你错了不能把typedef简单的当做文本拓展,其实它和第三个是一样的a为const指针。
二.const的赋值问题
1.元素赋值
定义const常量,必须在定义时就为该常量赋值,一个简单的例子(使用常量为const赋值)
Const int i//error
Const int i=5//ok
其实const不能称为常量,因为const的值是可以变化的,看下面的例子,
For(int j=1;j<5;j++)
Const int i=j;//ok
我也不明白从程序为什么可以运行,但是这就意味着我们可以用一个变量去初始化const常量,通过改变变量的值去修改 const的值,这种程序还是不用的好,因为这样就违反了const存在的初衷 但是i同样符合const的特性,一切视图使用变量名i去修改i的值的行为都会导致编译器报错 例如i=5//error 当然也可以使用const常量去初始化一个变量的值
其实这个涉及一个赋值时的对象复制问题,其实想想也是合理的,就不去深究啦!记住就好
2.指针引用赋值
Const最常用到的地方应该是指针和引用,指针和引用也存在不一样的地方,因为指针分为const指针和指向const对象的指针,而引用也就只用指向const对象的引用
首先说两者不一样的 const指针指的是const类型的指针,其指向不能改变,需要定义时赋值,一开始指向谁就以后就一直指向谁不能改变,可是其所指的对象的值却可以改变。例如
Const int* iptr//error
Const int*iptr=&a//ok;
*iptr=5;//ok
iptr=&b//error
而指向const类型对象的指针,其所指向可以改变,却不可以通过*iptr对对象的值进行改变,在定义时不必向上面那样对其赋值 可以在需要使用的时候在对它赋值。举个例子
Const int*iptr//ok;
iptr=&a;//ok
iptr=&b;//ok
*iptr=5//error;
也就是*iptr不能用作左值
有关引用就比指针更严格,定义const引用时,必须对该引用赋值,并且其引用的对象不能改变,这个没什么说的,可是在函数中const引用却用的最多
3.用const对象赋值其他类型的对象
说了那么多都在说对const对象的赋值,上面总结成一句话 const所定义的对象,除了在定义时,其他任何地方都不能用作左值(不知道对不对。。。)
下面说说用const对象赋值其他类型
首先用const对象赋值给const对象肯定是没问题的,当然如果是元素赋值,可以将const对象赋值给非const成员,涉及对象赋值,很好理解 如:
int j;
Const int i=5;
j=i;//ok;
而关于指向const对象的指针 这种指针只能赋值给相同类型的指针必须也为const ,与引用相同,不能将const类型的指针和引用赋值给非const类型的指针和引用。此处关于函数参数传递的问题,也就是因为这个我才开始了解const的。
还有const指针,,不说了,头有点晕,真的很绕人,说错了被打就不好了。。可能我理解的方法有问题。。Const指针可以赋值给非const指针,非const指针也可以赋值给const指针(仅限于初始化const指针的时候)。和元素赋值是一样的。
三.Const在函数中的应用
1.const用在函数前面,如
const int f1(void)
Const A f2(void)
Const A& f3(A&)
Const int*f4(void)
意思是函数的返回值是const,而第一种并不常见,因为系统定义的数据类型int本身返回的就是一个值,不可能是一个变量,用const修饰就没有意义。但是第二种,第三种返回值为const对象就可以避免下面的情况出现
f2()=A2;总是感觉出现这种的可能性不大,但是系统中很多这样的例子,比如a*b只能用作右值,当出现a*b=5时就会报错。
返回值虽然是const,但是仍然可以将返回值赋值给非const对象,当然第三个不可以赋值给非const的引用,却可以赋值给非const对象
例如
A a;
A&b;
a=f2()//ok
a=f3()//ok const引用可以赋值给非const对象(赋值是发生复制操作)
b=f3()//error const引用不能赋值给非const引用
对于第四个函数,返回值为一个指向const类型的指针,由于不能将const类型的指针和引用赋值给非const类型的指针和引用。故左值必须是指向const类型的指针,却又可以把const指针指向的值赋值给非const对象,故有下面的例子
Const int*a//ok
int *b;
Int c;
a=f4()//ok;
b=f4()//error 指向const对象的指针不能赋值给普通指针
c=*f4()//ok const对象可以赋值给非const对象(元素赋值问题)
PS:到目前为止我们很少使用过返回值为引用的函数,更如此很少将函数的返回值定义为const,因为返回的引用所指向的变量必须是全局变量,或者是主函数中使用的,我们可以将赋值=的重载定义为返回值为引用的函数,函数的返回值定义为const的情形多数在重载赋值操作符时出现!!!不到万不得以最好不要使用。
如 A& operator=(const A&a){};可以链式赋值
A a,b,c;
a=b=c;//ok
(a=b)=c//ok 但是不符合链式赋值的标准
此时就可以在函数前面加个const 这样第二种就不合法了。
2.const用在函数形参列表中
const所修饰的形参不可以改变,多数用于引用和指针的时候,为了保证传入的参数不被改变,
例如
Void f1(const int i)
Void f2(const int& i)
Void f3 (const int *i)
对于第一种存在的意义不大,因为本来的i就是传入参数的拷贝,传入参数本来就是安全的,所以不需要const,而第二种第三种就保护了传入的参数不发生改变。
PS:在定义类的成员函数的时候,对于不需要传入的参数发生改变时,一般都在形参前面加一个const,比如重载流操作符,重载关系运算符,默认构造函数。。。
3.Const用在函数体后(类的成员函数)
这种形式一般出现在类的成员函数中,目的是保护类的属性不会发生改变,在函数体内只能调用使用const在后修饰过得函数,一切可能会改变类的属性的函数都不能出现在该函数体内。一般只要在函数内不改变该类的属性的时候,都需要在函数后假如const,增加程序的健壮性
PS:当定义一个对象为const的时候,只能调用该对象的const用在函数体后的函数,
如const A a;
a只能调用此类函数,一切没有用const在后修饰的函数都不能调用
四.下面总结一下赋值问题
Const 对象 非const对象
Const引用 非const引用
Const指针 非const指针
指向const对象的指针 普通指针
“ ”指的是可以赋值
Const在初始化时,对初始化他的值可以是const类型,也可以是非const类型,但是在使用const常量为其他对象的指针和引用赋值时存在限制。
写这篇随笔的初衷:
一开始的我是不愿意涉及const的总觉得他的存在没有那么多的意义,在做程序设计时类的复制构造函数,以及重载等于操作符并没有使用const修饰形参,于是在将类放入vector中时,使用vector容器的push_back时出现了问题
下面贴出push_backde 源码
void push_back(const _Ty& _X)
{insert(end(), _X); }
下面是我遇到的问题:
Vector<R>Rs
Rs.push_back(R);
由于类中定义的复制构造函数传入参数为非const所以会报错
因为参数的传递大概是这样的:
非const对象 const引用 非const引用
后面的传递是传不过来的。
再瞎侃一下:
const有人说在c++中,与c中不相同已经归为常量,但是const与常量该是有很大的不同,毕竟我们可以把一个变量的值赋值给const,通过修改变量的值去修改此const常量的值。
在c++中我们可以定义一个const常量去作为数组的维数,如
Const int n=5;
Int a
;//ok
在c中是不可以的,数组的维数只能使用常量去定义,故此时的const可以认为就是常量
但是如果赋值时是变量 如:
Int j=5;
Const int i=j;//ok
Int a[i]//error C2057: expected constant expression
error C2466: cannot allocate an array of constant size 0
error C2133: 'a' : unknown size
所以在我看啊 const是否为常量应该由其初始化时的值所决定!(仅个人观点)
Const是c++中比较晦涩的部分,看了好久也只略懂一二。
相关文章推荐
- C++中有关const的一点心得
- C++有关继承的一点总结
- 有关C++字符转换的一点小总结
- 关于const的一点个人总结 C++
- C++ const的一点总结
- C++的const、指针、引用总结
- C++中的const限定词总结
- C++中const用法总结
- 有关因特网接入的一点总结
- 关于C++ const 的全面总结
- c++ const 用法总结
- c++的一点小总结
- 关于C++ const 的全面总结
- 关于C++ const 的全面总结
- C++中typedef、const、预处理等相关知识总结
- C++ const总结
- 关于C++ const 的全面总结
- 关于C++ const 的全面总结
- [C++] C++中const修饰指针,变量, 函数参数和函数返回值的用法总结
- C++中const用法总结