const修饰符使用详解
const修饰符的问题是本论坛上的一个常见问题,在此我做一个详细的解释,权当是抛砖引玉吧,欢迎各位网友一起探讨。const修饰符可以把对象转变成常数对象,即利用const进行修饰的变量的值在程序的任意位置将不能再被修改,就如同常数一样使用。例如:
const int a=1;//这里定义了一个int类型的常数变量a;
对指针来说const仍然是起作用的,我们来看一个例子:
#include <iostream>
using namespace std;
int main()
{
const int a=10;
int b=20;
const int *pi;
pi=&a;
cout <<*pi << "|" << a <<endl;
pi=&b;
cout <<*pi << "|" <<b <<endl;
return 0;
}
上面的代码中最重要的一句是 const int *pi,这句从右向左读作:pi是一个指向int类型的,被定义成const的对象的指针;这样的一种声明方式的作用是可以修改pi这个指针所指向的内存地址,却不能利用指针的解引用方式修改指向对象的值;如果你在代码后加上*pi=10;这样的赋值操作是不被允许编译的!const对象的地址只能赋给指向const对象的指针,但是指向const对象的指针可以被赋予非const对象的地址,只不过此时仍然无法通过该指针修改指向对象的值,不管这个对象是否是被定义成const的对象。
再来看一个例子:
#include <iostream>
using namespace std;
int main()
{
int b=20,c=30;
int * const pi=&b;
*pi=50;
//pi=&c;
cout<<*pi<<"|"<<b<<endl;
return 0;
}
上面的代码中最重要的一句是int * const pt,这句从右向左读作:pi是一个指向int类型的对象的const指针;这样的一种声明方式的作用是无法修改pi这个指针所指向的内存地址,却可以利用指针的解引用方式修改指向对象的值。如果把注释符取消掉,上面代码将不能通过编译。
下面这个例子中,把上面的两种声明方式结合到了一起:
#include <iostream>
using namespace std;
int main()
{
const int a=10;
int b=20;
const int *const pi=&a;
cout <<*pi << "|" <<a <<endl;
const int * const pt=&b;
cout<<*pt<<"|"<<b<<endl;
return 0;
}
上面的代码中最重要的一句是 const int *const pi,这句从右向左读作:pi是一个指向int类型的,被定义成const的对象的const指针;这样的一种声明方式的作用是你既不可以修改pi所指向对象的内存地址,也不能利用指针的解引用方式修改对象的值,因此在定义指针的时候就必须进行初始化,同时定义后也不能采用*pi=10这样的方式进行赋值,但是该类型的指针指向的对象不一定是const的,例如pt指向了b的地址。
在实际的程序中,指向const的指针常用作函数的形式参数,保证被传递给函数的实际对象在函数中不会被修改。来看一个交换数值的例子:
#include <iostream>
using namespace std;
void swap(int *a,int *b);
int main()
{
int a=3,b=5;
swap(&a,&b);
cout<<a<<"|"<<b<<endl;
return 0;
}
void swap(int *a,int *b)
{
int t;
t=*a;
*a=*b;
*b=t;
}
如果把swap函数的原型修改为void swap(const int *a,const int *b),那么程序将不能通过编译,因为swap函数体中,试图通过指针解引用方式修改a、b的值,根据上面的分析,这是不被允许的。
const修饰符还用在类的拷贝构造函数中,确认传入的对象不被修改。例如:
#include <iostream>
using namespace std;
class A
{
private:
int x;
public:
A(int t);
A(const A &p);
};
int main()
{
A a(3);
A b(a);
return 0;
}
A::A(int t)
{
x=t;
}
A::A(const A &p)
{
x=p.x+10;
}
《effective C++》这部经典名著中,第一条就是:尽量用const和inline而不用#define。const是#define的替换方案,详细原因请阅原书...