C++中const对象与const成员函数

    在自定义类型前加入const修饰符,可以将对象声明为常对象(如const MyClass A)。自定义类型的const常量不仅像基本数据类型那样不可以作左值,而且const对象的任意成员变量也不能被修改(mutable成员变量除外),为了保证const对象成员变量不能被修改,C++中规定了const对象只能调用一种特殊的成员函数——const成员函数。所谓const成员函数,就是不修改对象中任何一个变量的成员函数(mutable成员变量除外),但是不修改成员变量的函数不一定就是const成员函数。不修改任何成员变量的值的成员函数有资格成为const成员函数。有资格成为const成员函数的成员函数在函数首部的参数列表后加入const限定符,该成员函数成为const成员函数。在修改了非mutable成员变量的成员函数的参数列表后加入const限定符是编译错误。

    相同函数名、相同参数列表的const成员函数与非const成员函数是重载关系。对象调用成员函数的原则是:const对象只能调用const成员函数,非cosnt对象既能调用非const成员函数,又能调用const成员函数,如果同名同参数列表的const成员函数与非const成员函数同时存在(重载),非cosnt对象调用非const成员函数。

    由于const对象和非const对象都要调用构造函数和析构函数,因此构造函数和析构函数没有const函数与非const函数的区分。如果构造函数或析构函数中调用了同类的某个非const成员函数,不会影响const对象对该构造函数或析构函数的调用。

  #include<iostream>
  using std::cout;
  using std::endl;
  
  class Time
  {
  public:
  	Time(int h=0,int m=0,int s=0)
  	{
  		    set_hour(h);
  		set_minute(m);
  		set_second(s);		
  	}
  	void set_hour(int h)//非const成员函数
  	{
  		hour=h>=0&&h<=23?h:0;
  	}
  	void set_minute(int m)//非const成员函数
  	{
  		minute=m>=0&&m<=59?m:0;
  	}
  	void set_second(int s)//非const成员函数
  	{
  		second=s>=0&&s<=59?s:0;
  	}
  	int get_hour()const  //const成员函数
  	{
  		return hour;
  	}
  	int get_minute()  //有资格成为const成员函数,但不是const成员函数
  	{
  		return minute;
  	}
  	int get_second()const  //const成员函数
  	{
  		cout<<"const成员函数get_second()const被调用"<<endl;
  		return second;
  	}
  	int get_second()  //非const成员函数
  	{
  		cout<<"非const成员函数get_second()被调用"<<endl;
  		return second;
  	}
  private:
  	int hour;
  	int minute;
  	int second;
  };
  int main()
  {
  	Time afternoon(14,0,0);//非const对象
  	int h=afternoon.get_hour();//非const对象调用const成员函数
      int m=afternoon.get_minute();//非const对象调用非const成员函数
  	int s=afternoon.get_second();//非const对象调用非const成员函数
  	cout<<"afternoon="<<h<<":"<<m<<":"<<s<<endl;
  	afternoon.set_hour(15);//修改非const对象
  	cout<<"afternoon.hour="<<afternoon.get_hour()<<endl;
      
  	const Time noon(12,0,0);//const对象
  	h=noon.get_hour();//const对象调用const成员函数
  	//m=noon.get_minute();错误,const对象调用非const成员函数
  	s=noon.get_second();//const对象调用const成员函数
     	cout<<"noon="<<h<<":XX:"<<s<<endl;
  
  	return 0;
  }

显示结果:

非const成员函数get_second()被调用

afternoon=14:0:0

afternoon.hour=15

const成员函数get_second()const被调用

noon=12:XX:0

    程序的类型Time包括hour、minute和second等3个成员变量和构造函数、set_hour、set_minute、set_second、get_hour、get_minute以及2个版本的get_second等成员函数。其中set_hour、set_minute和set_second分别用于设置成员变量hour、minute和second的值,这3个成员函数修改成员变量的值,所以它们没有资格成为const成员函数,如果将它们声明为const成员函数(参数列表后加const关键字)将出现编译错误,构造函数中调用了这3个非const成员函数。函数get_hour、get_minute和get_second都没有修改任何成员变量的值,它们都有资格成为const成员函数。这里我们把get_hour声明为const成员函数(第27行),故意把get_minute声明为非const成员函数(第31行),同时把get_second声明为const和非const两个版本的成员函数(第35、40行)。

main函数中声明了Time类的非const对象afternoon(第52行),通过程序的显示结果可以看出,非const对象可以调用非const成员函数(第54、57行),也可以调用const成员函数(第53、58行),当调用const和非const两个版本同时存在的成员函数get_second时,非const对象调用非const版本的成员函数(第55行)。

main函数中又声明了Time类的const对象noon(第60行),虽然构造函数中调用了非const成员函数set_hour、set_minute和set_second,但是这并不影响const对象对构造函数的调用。通过程序的显示结果可以看出,const对象只可以调用const成员函数(第61、63行),不可以调用非const成员函数,哪怕该成员函数没有修改成员变量的值(第62行),当调用const和非const两个版本同时存在的成员函数get_second时,const对象调用const版本的成员函数(第63行)。

    另外,成员函数get_minute没有修改成员变量的值,但程序中却没有把它声明为const成员函数,造成了本应该能调用它的const对象无法调用该函数。因此,在编写自定义类型时,我们应该把那些没有修改成员变量的成员函数声明为const成员函数。



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值