知了博客

集天地之精华,吸日月之灵气

« extern用法详解住在隔壁的刚毕业的大学生小夫妻 »

const常类型说明

const : 不能修改


const常类型说明
    * 分类

    常变量:  const 类型说明符 变量名

    常引用:  const 类型说明符 &引用名

    常对象:  类名 const 对象名

    常成员函数:  类名::fun(形参) const

    常数组:  类型说明符 const 数组名[大小]    

    常指针:  const 类型说明符* 指针名 ,类型说明符* const 指针名

    * 实例说明

    const 类型说明符 &引用名 :

#include<iostream.h>
void display(const double& r)
{
// r=12.0;//错的
 cout<<r<<endl;
}
void main()
{
 double d=9.5;
 display(d);
}

   类名 const 对象名  与   类名::fun(形参) const

#include<iostream.h>

class R
{
public:
 R(int r1,int r2)
 {R1=r1;R2=r2;}
 void print();
 void print() const;
private:
 int R1,R2;
};
void R::print()
{ cout<<R1<<"::"<<R2<<endl; }

const int R::print() const
{ cout<<R1<<":"<<R2<<endl;
  return R1;}

void main()
{
 //常对象只能调用常成员函数,非常对象既可以调用普通成员函数也可以调用常成员函数(最佳匹配)
 R a1(5,4);
 a1.print();//调用void print()
 R const a(5,4);
 a.print();//调用void print() const  

 }

   类型说明符 const 数组名[大小]

void main()
{
 const int A[]={1,2,3,4,5,6,7,8,9,0};
 int const B[]={1,2,3,4,5,6,7,8,9,0};//两种定义都可以 

}

   const 类型说明符* 指针名  与  类型说明符* const 指针名

void main()
{
  int a=5;      
 int const *p=&a;//常类型中,const 与类型说明符的位置可互换
 a++;//可行
// *p=*p+2;//不可以
 cout<<*p<<endl;

 int b=100;
 const int *name1=&b;//值不便,地址可以变
 cout<<name1<<endl;
 name1=&a;
 cout<<name1<<endl;
// *name1=1;//错的 

 int n1=3, n2=5;
 int* const pn=&n1;
// pn=&n2;//错
 *pn=6;
 char* const name3="John";
// name3="abc";//错 

}

    * 注意事项

   1. 在常变量(const 类型说明符 变量名)、常引用(const 类型说明符 &引用名)、常对象(类名 const 对象名)、 常数组(类型说明符 const 数组名[大小]), const” 与 “类型说明符”或“类名”(其实类名是一种自定义的类型说明符) 的位置可以互换。如:

           const int a=5; 与 int const a=5; 等同

           类名 const 对象名 与 const 类名 对象名 等同
   2. 用函数fun(b)调用函数 fun(const double & a)中,实参b在main()中可以定义成const double b=5.0;,也可定义成double b=5.0; 。由引用的实质可知,a与b在内存中是同一个值,但若b定义成double b=5.0;,在main()中b是可重赋值的,而fun(const double & a)中则不可以,且b重新赋值会引起a值的改变。
   3. const 类型说明符* 指针名 的定义声明中,指针所指向的值不可以改变,但其所指向的地址可以变。如:  int a=11,b=100;
                             const int *name1=&b;
                             cout<<name1<<endl;
                             name1=&a;
                             cout<<name1<<endl;
                             // *name1=1;//错的
   4. 类型说明符* const 指针名 的定义声明中,指针所指向的值可以改变,但其所指向的地址不可以变。如:  int n1=3, n2=5;
                             int* const pn=&n1;
                             // pn=&n2;//错的
                             *pn=6;
   5.  常成员函数(类名::fun(形参) const),常对象只能调用常成员函数,非常对象既可以调用普通成员函数也可以调用常成员函数(最佳匹配)。

 ###########################################################################################

 
const

    * 一般常量:

            eg:int const x=2  或  const int x=2            两者无区别

    * 对象常量:

            eg:<类名>const<对象名>   或  const<类名><对象名>               两者无区别

    * 常指针:
          o  
                + int * const r=&n    (r是常量指针,不允许改变,所以:r=m是错误的,*r=1是允许的。)
                + const int *r=&n    (*r是常量,不允许改变,所以:r=m是允许的,*r=1是错误的。)

    * 常引用:

            const <类名>&<引用名>


    * 常成员函数:只有常成员函数才能操作常量或常对象。

            <类型><函数名>(<参数表>) const


    * 常数据成员:只能使用成员初始化列表的方式生成构造函数来对数据成员进行初始化

 

 ###########################################################################################

 

常对象和常函数的关系 const

http://blog.sina.com.cn/s/blog_4ac0a0d30100cmz5.html

(1) 常对象
用const修饰的对象叫对象常量,其格式如下:
〈类名〉const 〈对象名〉 或者 const 〈类名〉〈对象名〉
声明为常对象的同时必须被初始化,并从此不能改写对象的数据成员。


例:分析下列错误的地方,说明理由;
#include<iostream.h>
class Point
{ int x, y;
public:
Point(int a, int b) { x=a; y=b;}
Void MovePoint( int a, int b){ x+=a; y+=b;}
Void print(){ cout<<"x="<<x<<"y="<<y<<endl;}
};
void main( )
{
const Point point1( 10,10);//常量对象
point1.MovePoint(2,2);//常对象point1的数据不能被更改,所以错误
point1.print( );//print函数的this指针不能指向常对象
}
错误原因在旁边已经注释。
常对象常被用在对象的引用上。所谓常引用是指说明引用时用const修饰。常引用所引用的对象不能被更新,一般用做形参。其格式:
const 〈类型说明〉&〈引用名〉
例:根据例题5-11的类给出程序的执行结果:
#include<math.h>
int length(const Point &p1, const Point &p2)
{ int l;
l=sqrt((p1.x -p2.x)* (p1.x -p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
return l;
}
void main( )
{
Point a(1,1),b(4,5);
Cout<<"两点的距离是:"<<length( a, b)<<endl;
}
本程序的输出:
两点的距离是:5
(2)常成员函数
用const关键词说明的函数叫常成员函数。其格式如下:
〈类型〉〈函数名〉(〈参数表〉)const;
常成员函数的作用和功能:
常成员函数不能更新对象的数据,也不能调用非const修饰的成员函数。常对象只能调用类的常成员函数。
例:给出下列程序的执行结果:
#include<iostream.h>
class Point
{ int x, y;
public:
Point(int a, int b) { x=a; y=b;}
Void MovePoint( int a, int b){ x+=a; y+=b;}
Void print()const { cout<<"x="<<x<<"y="<<y<<endl;}
};
void main( )
{
Point point1(1,1);
const Point point2( 2,2);//常量对象
point1.print();//普通对象可以调用常成员函数
point2.print( );//常对象调用常成员函数
}
本程序执行结果:
x=1 y=1
x=2 y=2

使用const关键字说明的成员函数称为常成员函数,常成员函数的说明格式如下:
    <返回类型说明符> <成员函数名>(<参数表>) const;
    在使用常成员函数时要注意:
    (1) const是函数类型的一个组成部分,因此在函数实现部分也要带有const关键字。
    (2) 常成员函数不更新对象的数据成员,也不能调用该类中没有用const修饰的成员函数。
    (3) 常对象只能调用它的常成员函数,而不能调用其他成员函数。成员函数与对象之间的操作关系如表12-1所示。

常对象和常函数的关系 <wbr>const

来源:(http://blog.sina.com.cn/s/blog_4ac0a0d30100cmz5.html) - 常对象和常函数的关系 const_天涯霜雪_新浪博客

 

    (4) const关键字可以用于参与重载函数的区分。例如:
    void Print();
    void Print() const;
    这两个函数可以用于重载。重载的原则是:常对象调用常成员函数,一般对象调用一般成员函数。
  (5)在const成员函数中:  
  可以修改被定义成mutable的成员变量,使用mutable关键字定义的成员变量可以被const成员函数修改!

     保护类的成员变量不在成员函数中被修改,是为了保证模型的逻辑正确,通过用const关键字来避免在函数中错误的修改了类对象的状态。并且在所有使用该成员函数的地方都可以更准确的预测到使用该成员函数的带来的影响。而mutable则是为了能突破const的封锁线,让类的一些次要的或者是辅助性的成员变量随时可以被更改。没有使用const和mutable关键字当然没有错,const和mutable关键字只是给了建模工具更多的设计约束和设计灵活性,而且程序员也可以把更多的逻辑检查问题交给编译器和建模工具去做,从而减轻程序员的负担(yayv觉得这只不过是把负担移交给了设计人员~, :(,并没有降低任何工作量 )。如果开发过程有比较严格的迭代过程,使用这两个关键字应该更能体现出他们的作用。


来源:http://my.oschina.net/alphajay/blog/5749

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

日历

最新评论及回复

最近发表

Powered By Z-Blog 1.8 Arwen Build 90619 Code detection by Codefense  theme by BokeZhuti

Copyright know blog. Some Rights Reserved.站长(msn):webmaster#webgou.info(#换成@) 粤ICP备09183716号