const主要是为了程序的健壮型,减少程序出错.
最基本的用法:
const int a=100; b
的内容不变,b只能是100也就是声明一个int类型的常量(#define b =100)
int const b=100; //
和上面作用一样 

const
指针和引用一般用在函数的参数中
int* m = &a; //
出错,常量只能用常指针
int c= 1;const int*pc = &c;//
常指针可指向常量 

const int* pa = &a; //
指针指向的内容为常量(就是b的值不变)
int const *a = &b; //
指针指向的内容为常量(就是b的值不变)*p=3//error
int* const a = &b; //
指针为常量,不能更改指针了如 a++但可以改值*p=3; 

从这可以看出const放在*左侧修饰的是指针的内容,const放在*右侧修饰的是指针
本身

const
引用的用法和指针一样
int const & a=b;
和指针一样
const int& a=b;
和指针一样
但没有 int& const a=b 的用法因为引用不能做移位运算,但只是出个warning 

const int* const a = &b; //
综合应用,一般用来传递多维的数组
类如:char* init[] = {"Paris","in the","Spring"};
void fun(const int* const a){}
fun(init)//
保护参数不被修改 

int A(int)const; //
是常函数,只能用在类中,调用它的对象不能改改变成员值
const int A(); //
返回的是常量,所以必须这么调用 cosnt int a=A();
int A(const int); //
参数不能改值,可用在任意函数
int A(const int*);
....
int height() const;//
常函数只能由常函数调用
int max(int,int) const;
int Max = max(height(),height()); 

const int* pHeap = new int;
delete pHeap;
p = NULL;//
出错
我的解决办法是强制类型转换
const int* pHeap = new int(1);
delete (int*)pHeap;
pHeap = NULL; 

一、const 和引用联合使用的时候要注意 

const int a = 1; 
const int& ref1 = a;
const int& ref2 = 1; 

ref1
ref2 都是正确的,但是他们引用的内容和一般的引用不同
const int& ref1 = a; 而言,其实这个 ref1 已经和 a 没有任何关系了
ref1
实际上是对一个临时量的引用。同理 const int& ref2 = 1; 也是对
一个临时量做的引用。当引用临时量是 C++ 的隐式类型转换可以起作用。
临时量的生存期和引用量的生存期相同。 

二、强传const对象可能导致无定义行为 

对于优化做的比较好的编译器,代码 const int i = 1;
当后面用到变量 i 的时候,编译器会优化掉对 i 的存取,而直接使用立即数

const int i = 1; 

*(const_cast<int*>(&i)) = 2;
cout << *(int*)&i << endl;
cout << i << endl; 

所以,对 const 对象做 const_cast 可能导致无定义行为
目前我就遇到这些问题,那位还有补充的吗 





能不能把自己的经验也谈谈。大家交流交流
这个就是我在调错时发现的
int height() const;//
常函数只能由常函数调用
int max(int,int) const;
int Max = max(height(),height()); 





Thinking again in C++
(一)常量性原理 cphj(原作) 
有些地方很受启发 


1.
不能将const修饰的任何对象、引用和指针作为赋值表达式的左值。
const int cx=100;
const int & rcx=cx;
const int * pcx=&cx;
cx=200; //error
rcx=200; //error
*pcx=200; //error 

2.const
类型的对象不能直接被non-const类型的别名所引用。
(1)
不能将const类型的对象传递给non-const类型的引用。
const int cx=100;
int & rx=cx; //error
(2)
不能将const类型的实参传递给形参为non-const类型引用的函数。
void f(int a)
{
}
void g(int & ra)
{
}
const int cx=100;
f(cx); //ok
g(cx); //error
(3)
不能将const类型的对象作为non-const类型引用的函数返回值。
int & f(const int & rca)
{
return rca; //error
}
int x=100;
f(x); 

3.
可以使用const类型别名引用non-const对象。此时通过const引用不能修改对象,但对象可以通过non-const引用被修改。
int x=100;
int & rx=x;
const int & rcx=x; //ok
x=200;
rx=200;
rcx=200; //error 

4.
指针的属性有两个:指针的类型和指针本身的常量性。其中,指向const对象与指向non-const对象,是不同的指针类型。
int x=100;
const int * pcx=&x; //[1]
int * px=&x; //[2]
int y=100;
int * const cpy=&y; //[3]
int * py=&y; //[4]
[1][2]
两个指针的类型不同;[3][4]两个指针的常量性不同。
对象与指向对象的指针的规则类似于对象与引用。即,const类型的对象不能直接被non-const类型的指针所指示(同2);可以使用const类型的指针指向non-const对象(同3)。 

5.
可以将相同类型(包括常量性)的const指针值赋给non-const指针。
int x=100;
int * px;
const int * pcx=&x;
px=pcx; //error
int * const cpx=&x;
px=cpx; //ok 

6.
若函数的返回值为内建类型或是指针,则该返回值自动成为const性质。但自定义类型则为non-const性质。
int f() //
相当于返回const int
{
return 100;
}
int * g(int & ra) //
相当于返回int * const
{
return &ra;
}
class CTest
{
int n;
public:
CTest(int n){this->n=n;}
};
CTest h() //
返回的就是CTest
{
return CTest(200);


f()=200; //error 

int x=100;
int y=200;
int * px=&x;
g(y)=px; //error
*g(y)=x; //ok
,从这点可以看出g()返回的不是const int * 

CTest t(100);
h()=t; //ok
,但却是完全错误的、危险的做法
//
所以h()的正确写法是返回const CTest





const int b=100; b
的内容不变,b只能是100
int const b=100; b
必须为int,不能为其他类型?
2句话的意思应该是一样的吧 , THINKING IN C++是这样说的





const int a=100; a
的内容不变,a只能是100(同样不能类型转换)。
int const b=100; b
必须为int,不能为其他类型?(同样在使用中不能修改)。
所以ab是一样的,称为整型常数,在使用中不能被修改,当然都不能转为其他类型了。 
#include <iostream> 

using namespace std; 

int main()
{
  const int a = 100;
  int const b = 100; 

  a = 100; //这四条语句编译时都会出现“Cannot modify a const object 
b = 100; //in function main()
”的错误提示,也就是说,任何企图修改   a = 100.0; //ab(其实是一样的)的行为都会出现“灾难”,在语法上讲就  b = 100.0; //ab都不能出现在赋值语句的左边! 

  cout<<'\n'<<a<<'\n'<<b<<endl; 

  return 0;
}





常函数的调用是这样的:常量对象只能调用常成员函数,非常量对象即可以调常成员函数,也可以调一般成员函数,但当某个函数有const和非const两个版本时,const对象调const版本,非const对象调非const版本
例:
class A
{
public:
int & GetData(){return data;}
const int & GetData()const {return data;}
private:
int data;

A a;
a.GetData();//
调用int & GetData(){return data;}
//
但如果没有这个函数,也可以调用const int & GetData()const 
const A const_a;
const_a.GetData();//
调用const int & GetData()const {return data;}
常函数只能调常函数,也是由于这个原因





算你狠!加两点

一、const 和引用联合使用的时候要注意 

const int a = 1; 
const int& ref1 = a;
const int& ref2 = 1; 

ref1
ref2 都是正确的,但是他们引用的内容和一般的引用不同
const int& ref1 = a; 而言,其实这个 ref1 已经和 a 没有任何关系了
ref1
实际上是对一个临时量的引用。同理 const int& ref2 = 1; 也是对
一个临时量做的引用。当引用临时量是 C++ 的隐式类型转换可以起作用。
临时量的生存期和引用量的生存期相同。 

二、强传const对象可能导致无定义行为 

对于优化做的比较好的编译器,代码 const int i = 1;
当后面用到变量 i 的时候,编译器会优化掉对 i 的存取,而直接使用立即数

const int i = 1; 

*(const_cast<int*>(&i)) = 2;
cout << *(int*)&i << endl;
cout << i << endl; 

所以,对 const 对象做 const_cast 可能导致无定义行为





#include <iostream.h>
void fun(char b){cout <<"void"<<endl;}
int fun(int const b){cout <<"int"<<endl;} 
int main()
{
fun(1.0);//
详细看看重载函数吧 
fun(4); //
想一想调用哪一个 

return 0;
}
我试了一下,会出错? vc说:'fun':ambiguous call to overloaded function 





补充的好啊,这个一般不会注意的
const int i = 1;
*(const_cast<int*>(&i)) = 2;
cout << *(int*)&i << endl;
cout << i << endl;
这个可真有意思,调试时两个都是2,可编译就是21
const
的永远都是const,这样能更改就不错了,不然就自相矛盾了
奇怪的是 pi &i地址一样啊,就像楼上说的这是编译时的优化
处理
const int i = 1;
int* pi=const_cast<int*>(&i);
*pi=2;
cout << *pi << endl;
cout << i << endl; 





那个主要是隐式转换
你可依次把两个函数注掉看看调用
#include <iostream.h>
//void fun(char b){cout <<"void"<<endl;}
void fun(int b){cout <<"int"<<endl;}
int main()
{
fun('a');
fun(4); 
return 0;
}
Posted on 2005-12-09 10:54 艾凡赫 阅读(47921) 评论(13)  编辑 收藏 引用 所属分类: 基础知识

Feedback

# re: const用法  回复  更多评论   

2007-10-05 22:25 by 金鹏
前辈啊,我初学者,看不懂你们在说什么啊.怎么办啊!

# re: const用法  回复  更多评论   

2007-10-09 09:01 by ivenher
多多尝试,有了手感就好了

# re: const用法  回复  更多评论   

2007-12-27 21:48 by 张飞
@金鹏
蠢猪!

# re: const用法  回复  更多评论   

2008-01-17 14:57 by harer
很好,收藏了。
谢谢。

# re: const用法  回复  更多评论   

2008-02-08 20:22 by 敖马
不得不说博客主人谈的很细致,看得出来经验丰富啊~
作为一个初学C++的小毛孩,我对C++还没"感觉",不过编程就是这样,入门容易,精通难,本身的多读多练很重要.当然了,能看到前辈这样的经验之谈也很有帮助,作为晚辈的我们说不定哪天遇到了问题就可以少走一点弯路~

谢了哈~~^_^

# re: const用法[未登录]  回复  更多评论   

2008-03-20 00:21 by me
发现其中有不少错误

# re: const用法  回复  更多评论   

2008-04-29 16:15 by 程诚成
今天又复习了一遍,收藏了,很全面。

# re: const用法  回复  更多评论   

2008-07-26 16:04 by 啊啊
说的太深奥了

# re: const用法  回复  更多评论   

2009-01-09 15:24 by bigcoder
貌似其中有错误

# re: const用法  回复  更多评论   

2009-03-31 12:31 by akxxx
错误很多。。。。

# re: const用法  回复  更多评论   

2009-10-22 14:59 by kakayunmu
很好很详细

# re: const用法  回复  更多评论   

2009-11-21 14:40 by alan
错误很多 COPY的吧。。。

# re: const用法[未登录]  回复  更多评论   

2010-05-07 17:50 by a
const int A(); //返回的是常量,所以必须这么调用 cosnt int a=A();
这里错了!
直接这样调用就行
int a = A();

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理