【C++】class的设计与使用(三)mutable(可变)和const(不变)

const

class Triangular{
public:

	int length() const{return _length;}
	int beg_pos() const{return _beg_pos;}
	int elem(int pos) const;

	bool next(int &val);
	void next_reaset()
	{
		_next=_beg_pos-1;
	}
	static vector<int>_elems;
  • const修饰符紧接在函数参数列表之后(告诉编译器:这个成员函数不会更改类对象的内容);
  • 编译器会检查每个声明为const的成员函数,检看看他们是否真的没有改变类对象的内容,如果改变,就会产生编译错误;
  • 在class主体以外定义的成员函数,如果它是一个const成员函数,那就必须同时在声明定义中指定const:
int Triangular::elem(int pos) const
{
	return _elems[pos-1];
}
  • 然而返回一个非const引用,引用(“指向”)标注着const的成员函数的函数体内的对象也会产生问题:将标const的成员函数的函数体内的对象开放了出去,允许程序在其他地方加以修改:
class val_class{
public:
	val_class(const BigClass &v)
		:_val(v){}
		
	//有问题
	BigClass& val()const 
	{
		return _val;
	}
private:
	BigClass _val;
}

解决:
提供两份定义:const版本和non-const版本

class val_class{
public:
	const BigClass& val() const{return _val;}
	BigClass& val() {return _val;}
};

//non-const的类对象会调用non-const的成员函数val()
//const的类对象调用const版的成员函数val()
void example(const BigClass *pbc, BigClass &rbc)
{
	pbc->val();//调用const版本的成员函数val()
	rbc.val();//调用非const版本的成员函数val()
}

设计类时,必须鉴定类的const成员函数
没有一个const引用类参数可以调用公开接口(public:)中的non-const成分(但目前很多编译器对此情况都只给警告)

mutable

int sum(const Triangular &trian)
{
	if(!trian.length())
		return 0;
	
	int val,sum=0;
	trian.next_reset();
	while(trian.next(val))
		sum+=val;

	return sum;
}
//trian是个const类对象
//但next_reset()函数和next()函数都会更改_next的值
//需要关键字mutable:
class Triangular{
public:
	bool next(int &val)const;
	void next_reset()const
	{
		_next=beg_pos-1;
	}
	//...
private:
	mutable int _next;
	int _beg_pos;
	int _length;
};
//next_reset()函数和next()函数既可以修改_next的值
//又可以被声明为const成员函数

关键字mutable:对数据成员所做的改变并不会破坏类对象的常量性

你可能感兴趣的:(C++基础,c++,开发语言,笔记,算法)