C++:常类型Const


常类型:使用类型修饰符const说明的类型,常类型的变量或对象成员的值在程序运行期间是不可改变的。

3.10.1 常引用

如果在说明引用时用const修饰,则被说明的引用为常引用。如果用常引用做形参,便不会产生对实参
的不希望的更改。常引用的说明形式如下:

const 类型 &引用名;

例如:int a=5;
const int &b=a;
其中,b是一个常引用,它所引用的对象不允许更改。如果出现:b=12 //则是非法的

在实际应用中,常引用往往用来作形参,这样的参数称为长形参

3.39  常引用作函数的参数           
*/
#include<iostream>
using namespace std;
int add(const int &,const int &);  //声明add的形参是常引用 
int main()
{
  int a=20;
  int b=30;
  cout<<a<<"+"<<b<<"="<<add(a,b)<<endl;
  
  a = 15;     //在add函数外,实参是可以改变的 
  b = 50;     //在add函数外,实参是可以改变的
  cout<<a<<"+"<<b<<"="<<add(a,b)<<endl;
  
  return 0; 
}
int add(const int &i,const int &j)   //常引用作函数形参 
{
  //i=i+20;      //不允许改变i的值 
   return i+j; 
} 

/*
程序运行结果: 20+30=50
               15+50=65
               
               
说明:由于add函数两个形参都定义为常引用,所以在函数中不能改变i和j的值,如果改变它们的
      值,编译将会出错,如本程序中执行的函数add加有注释的语句"i=i+20;",将会出现编译
      错误。因此,用常引用作形参,能够避免对是实参的更改,保证了数据的安全性。                
*/

3.10.2 常对象

如果说明对象时用常引用const修饰,则被说明的对象为常对象。常对象的数据成员值在
在对象的整个生存周期内不能被改变。常对象的说明形式如下:

类名 const &对象名[(参数表)]

或 const 类名 &对象名[(参数表)]

在定义对象时必须被初始化,而且不能被更新。

3.40   非常对象和常对象的比较  
*/
#include<iostream>
using namespace std;
class Sample{
    public:
        Sample(int m,int n)
        {
          i = m;
          j = n;
        }
        int j;
        void setvalue(int x)
        {
          i = x;
        }
        void show()
        {
          cout<<"i="<<i<<endl;
          cout<<"j="<<j<<endl;
        }
    private:
       int i;
           
};
int main()
{
Sample s(10,20);  //对象s是普通对象,而不是常对象 
s.setvalue(30);
s.j=40;
s.show();  //运行结果是 i=30 j=40 


/*
Sample const s(10,20); //对象s是常对象
s.setvalue(30);  //运行错误,C++不允许间接的更改i的值 
s.j=40;   //运行错误,C++不允许置接的更改j的值 
s.show(); //运行错误,C++不允许常对象调用普通的 
*/

return 0;
}

3.10.3 常对象成员

1. 常数据成员
类的数据成员可以是常量或常引用,使用const说明的数据成员称为常数据成员。如果在
一个类中说明了常数据成员,那么构造函数就只能通过成员初始化列表对该数据成员进行
初始化,而其他人任何函都不能对该成员赋值。

   例3.41  常数据成员的使用            
*/
#include<iostream>
using namespace std;
class Date{
  public:
    Date(int y,int m,int d);
    void show();
  private:
    const int year;    //常数据成员 
    const int month;   //常数据成员
    const int day;     //常数据成员
};
Date::Date(int y,int m,int d):year(y),month(m),day(d){} //采用成员初始化列表,对数据成员进行初始化 
void Date::show()
{
  cout<<year<<".";
  cout<<month<<".";
  cout<<day<<endl;
} 
int main()
{
 Date date1(2015,5,7);  
 Date date2(2015,5,8); 
 date1.show();
 date2.show();
 return 0;
}

/*
  运行结果为:2015.5.7
                2015.5.8
  
  该程序中定义了如下3个常数据成员:
          const int year;    //常数据成员 
          const int month;   //常数据成员
          const int day;     //常数据成员
          
其中year、month、day是int类型的数据成员。需要注意到是构造函数的格式如下:

     Date::Date(int y,int m,int d):year(y),month(m),day(d){}
     
     其中,冒号后面是一个成员初始化列表,它包含3个初始化项。这是由于year、month、
     和day都是常数据成员,C++规定只能通过构造函数的初始化列表对常数据成员进行初始化。
     在函数体中采用赋值语句对数据成员直接赋初值是非法的。如以下形式的构造函数是错误的:
     
          Date::Date(int y,int m,int d)
          {
            year = y;     //非法 
            month = m;    //非法
            day = d;      //非法
          }
          
   一旦对某对象的常数据成员初始化后,该数据成员的值是不能改变,但不同对象中的该数据成员
   的值可以是不同的(在定义对象时给出) 如: Date date1(2015,5,7);   
                                                Date date2(2015,5,8);
*/

2、常成员函数

在类中使用关键字const说明的成员函数为常成员函数,常成员函数的说明格式如下:

类型说明符 函数名(参数表) const;

const是函数类型的一个组成部分,因此在声明函数和定义函数时都要用关键字const,
在调用时不必加const。

例3.42 常成员函数的使用             
*/
#include<iostream>
using namespace std;
class Date{
  public:
    Date(int y,int m,int d);
    void show();          //声明普通的成员函数show() 
    void show() const;    //声明常成员函数show() 
  private:
     const int year;      //常数据成员 
     const int month;     //常数据成员
     const int day;         //常数据成员
/*
      int year;   //普通数据成员 
      int month;  //普通数据成员
      int day;    //普通数据成员
*/
};
Date::Date(int y,int m,int d):year(y),month(m),day(d){} //定义构造函数,采用成员初始化列表,
                                                        //对数据成员进行初始化

void Date::show()            //定义普通的成员函数show()
{
  cout<<"Date::show1()"<<endl;
  cout<<year<<".";
  cout<<month<<".";
  cout<<day<<endl;
} 
void Date::show() const       //定义常成员函数show()                                  
{
  cout<<"Date::show2()"<<endl;
  cout<<year<<".";
  cout<<month<<".";
  cout<<day<<endl;
} 
int main()
{
 Date date1(2015,5,7);       //定义普通对象date1
  date1.show();              //调用普通的成员函数show 
   
 const Date date2(2015,5,8); //定义常对象date2 
 date2.show();               //调用常成员函数show
 
 return 0;
}

/*
 程序运行结果如下:
                    Date::show1()
                    2015.4.7 
                    Date::show2()
                    2015.4.8 
 
    本程序中,类Date中说明了两个同名成员函数show,一个是普通成员函数,另一个是常成员函数,
    它们是重载的。可见,关键字const可以被用于区分重载函数。

说明:

1、常成员函数可以访问常数据成员,也可以访问普通数据成员。常数据成员可以被常成员函数访问,
也可以被普通成员函数访问。

2、如果将一个对象说明为常对象,则通过该对象只能调用它的常成员函数,而不能调用普通的成员
函数。常成员函数是常对象唯一的的对外接口,这时C++从语法上对常对象的保护。

表3.2 常成员函数和普通成员函数的访问特性比较
--------------------------------------------------------------------------------------------------------------- 
数据成员 |                         普通成员函数 |                               常成员函数
--------------------------------------------------------------------------------------------------------------- 
普通数据成员                 可以访问,也可以改变值               可以访问,但不可以改变值

常数据成员                     可以访问,但不可以改变值           可以访问,但不可以改变值

常对象的数据成员         不允许访问和改变值                       可以访问,但不可以改变值

3、常成员函数不能更新对象的数据成员,也不能调用该类中的普通成员函数,这就保证了在常成员
函数中绝对不会更新数据成员的值。

 

posted @ 2015-10-26 19:42  XYQ全哥  阅读(365)  评论(0编辑  收藏  举报