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:对数据成员所做的改变并不会破坏类对象的常量性