const与类成员函数

时间:2022-06-20 19:12:54

既然类的实例是个对象,那么它也应该可以被const修饰。按照const的定义,

const SampleClass foo_const;

SampleClass foo;

并不是同样的东西。简单来说,foo_const不能被改变,显然也就是它的字段不能被改变。那么普通的对象foo能做的事情foo_const是不是也能做呢。

例如,我们的类是这样的

class SampleClass{

      private:

              int value;

      public:

             void changeValue() { value=10; }

}

显然,foo.changeValue()完全没有问题,可是foo_const.changeValue()就显得不太合适,总不能一边告诉我你是常量一边欢迎我改变你的值吧。果然,编译它的话一定会出现下面的错误信息:

cannot convert ‘this’ pointer from ‘const class SampleClass’ to ‘class SampleClass &’

如果一个成员函数没有把传递给它的this指针指定为const,编译器就不允许const对象调用它。

那么是不是const对象就不能调用成员函数呢?肯定不是,成员函数中也可以不改变成员的值呀。比如:

int getValue(){return value;}

这个函数没有改变任何东西,但是编译器不知道啊,所以它还是不允许可怜的foo_const调用。所以我们需要给编译器一个明确的标识。

int getValue() const {return value;}

在函数的括号后面加上const,表示这个函数不会改变类的数据成员。const对象因此也就可以放心大胆的调用它了。如果谁不小心在const成员函数的函数体里面把数据成员写在了等号的左边,没有关系,编译器一定会报告一个error

值得注意的是,int getValue() constint getValue()完全是两个函数,const也是函数类型的一部分,如果要在类的外面定义int getValue() const,写成inline int getValue()编译器会报错。那么,如果两个都写上,岂不是也算是一种重载?正确,万一哪天有人出题说要尽量多的重载,const也是一个利器啊^_^

总之,对于一个类来说只要是不改变自己的数据成员的函数咱们都应该给它加上const,使它成为const函数。

在成员函数中我们还经常看见const出现在返回值的前面。这真是诡异,我们明白这是告诉编译器这个函数的返回值不允许改变,可是谁会傻到写这样的代码呢?

foo.getValue()=20;

可是总有人会写出这种句子来,

(a=b)=c;

这不就是a.operator = (b)=c么,所以const修饰返回值也不是不应该。

当然还有一种讨厌的情况,万一我想在const函数里面修改数据成员的值应该怎么办。

办法不是没有,比如说const_cast可以用蛮力去掉const,不过这个方法显然不被推荐。

另一个方法是在数据成员声明的时候就说清楚,这个成员一定是可变的,不存在什么常量的情况。

class SampleClass{

      private:

              int value;

              mutable bool flag;

}

即使声明const SampleClass foo_const;,我们也一样可以改变flag的值。

 

http://iask.sina.com.cn/b/15709919.html