一、const用在函数中:
注意:const 类型只能赋值给const类型
如下几种运用方式
A& operator=(const A& a);
void fun0(const A* a );
void fun1( ) const; // fun1( ) 为类成员函数
const A fun2( );
-
const 用在函数的返回类型中,一般情况下,不用这种返回类型。
const A fun2( );
2.类的成员函数后面加 const,表明这个函数不会对这个类对象的数据成员(准确地说是非静态数据成员)作任何改变。 void fun1( ) const;
在设计类的时候,一个原则就是对于不改变数据成员的成员函数都要在后面加 const,而对于改变数据成员的成员函数不能加 const。所以 const 关键字对成员函数的行为作了更加明确的限定:有 const 修饰的成员函数(指 const 放在函数参数表的后面,而不是在函数前面或者参数表内),只能读取数据成员,不能改变数据成员;没有 const 修饰的成员函数,对数据成员则是可读可写的。
除此之外,在类的成员函数后面加 const 还有什么好处呢?那就是常量(即 const)对象可以调用 const 成员函数,而不能调用非const修饰的函数。
#include<iostream>
using namespace std;
class A{
public:
A(int a=0 ,int b=0 );
const A& operator=(const A& a);
friend ostream& operator<<(ostream &os, const A& a);
friend const A operator+(const A& a, const A& b);
void setA(int ,int );
int getb()const{ return b; }//一般情况不修改数据成员的函数都要修饰成cosnt
int getc()const{ return c; }
private:
int b, c;
};
const A operator+(const A &x, const A& y){//这里声明返回类型中加上const目的
//防止a+b=c.这种情况通过
A m;
m.b = x.b + y.b;
m.c = x.c + y.b;
return m;
}
ostream& operator<<(ostream &os, const A& a){
os << a.b << endl;
os << a.c << endl;
return os;
}
A::A(int m, int n){ setA(m, n); }
void A::setA(int m,int n){
b = m;
c = n;
}
const A& A::operator =(const A& a){//一般不加const
b = a.b;
c = a.c;
return *this;
}
const A& max(const A& v1, const A& v2){//这里参数都被声明为const引用。所以返回值也为
//const 修饰的类,只能调用const修饰的函数!
if (v1.getb()>v2.getb()){ return v1; }
else
{
return v2;
}
}
int main(){
const int s = 2;//声明一个变量时必须进行初始化
//const int d;报错must be initialed if not extern;
A a(2,3), b, c;
c=b=a;
//(c = b) = a;错误的因为(c=b)返回一个const值无法在被赋值。
cout <<"第一次\n"<< a<<b<<c<<endl;
b.setA(10, 5);
c = max(b, c);
cout << "第二次\n"<<a << b << c << endl;
c = a + b;
//a + b = c;这里a+b返回类型被声明为const A ,所以创建的对象不可以被赋值。
system("pause");
return 0;
}
二、const 用在变量中
1.const 修饰的全局变量是具有内部链接性!在这点上与static 修饰全局变量相似。
2.const修饰变量一般有两种方式:const T *a,或者 T const *a
看*号的位置:const T *a 指一个指针a 指向 const修饰的 T类型变量。
a可以被赋值但是 *a就不可以复制。
#include<iostream>
using namespace std;
int main(){
const int v1 = 3;
//int * p1 = &v1;错误的,因为不能修改,你用一个指向可以修改的int型的指针肯定不可以
int v2 = 3;
const int *p2 = &v2;
//很微妙,不可以用*p2修改v2。
//*p2 = 2;错误
v2 = 4;//正确;
const int v3 = 3;
const int *p3 = &v3;//这种情况下通过*p3 或v3都无法修改v3的值。
//v3 = 4;错误
//*p3 = 4;错误
p3 = p3 + 1;//这个却可以编译通过
const int v4 = 3;
const int * const p4 = &v4;
//p4 = p4 + 1;invalid p4指针的指向 不允许改变
}
3.const 变量声明时必须初始化。
但是若是在类里声明的注意:因为类可以创建多个对象,不同的对象其const数据成员的值可以不同。所以不能在类声明中初始化const数据成员
class A
{
const int size = 100; //错误
int array[size]; //错误,未知的size
}
三、 const 的好处:
可以避免不必要的内存分配
#define STRING "abcdefghijklmn\n"
const char string[]="abcdefghijklm\n";
...
printf(STRING); //为STRING分配了第一次内存
printf(string); //为string一次分配了内存,以后不再分配
...
printf(STRING); //为STRING分配了第二次内存
printf(string);
...
由于const定义常量从汇编的角度来看,只是给出了对应的内存地址,
而不是象#define一样给出的是立即数,所以,const定义的常量在
程序运行过程中只有一份拷贝,而#define定义的常量在内存中有
若干个拷贝。
本文转自 神迹难觅 51CTO博客,原文链接:http://blog.51cto.com/ji123/1916799,如需转载请自行联系原作者