C++的那些事:const用法面面观
作者:网络转载 发布时间:[ 2014/6/10 11:30:03 ] 推荐标签:C++ net
在成员函数调用的过程中,都有一个 this 指针被当做参数隐性地传递给成员函数(可能通过栈,也可能通过CPU寄存器)。这个this指针,指向调用这个函数的对象(这样,成员函数才能找到成员变量的地址,从而对其进行操作)。这个this指针,是个 const指针,不能修改其指向(你不希望这个对象的函数,修改了那个对象的成员变量,对吧?)。
传递给const成员函数的this指针,指向一个const对象。也是说,在const成员函数内部,这个this指针是一个指向const对象的const指针。
mutable 修饰符使得const函数的行为有了一些灵活性。相当于提醒编译器,这个成员变量比较特殊,不要进行任何只读检查了。
为什么 const 对象只能够调用const成员函数呢?,其实是这样的。由于对象本身通过 const 修饰,那么指向这个对象的指针也是指向const对象的const指针了。换句话说,指向这个对象的this指针是指向const对象的const指针。一般成员函数要求的this指针为:指向对象的const指针。所以此处发生了参数不匹配,无法进行调用。而 const 成员函数要求的this指针,恰恰是 指向const对象的const指针。所以依然能够调用。
八、const与函数
将函数的形参用const修饰是希望实参在函数内部不被修改,而一般函数接口可能会遇到以下三种情况:
1,const对象
2,指向const对象的指针
3,绑定const对象的引用
4,返回值是一个const对象
首先,我们看const对象的形参,这种接口用const修饰实际上没有任何意义,因为实参在传递给实参时是传递了一份副本,原实参是不会变化的。
传递给const成员函数的this指针,指向一个const对象。也是说,在const成员函数内部,这个this指针是一个指向const对象的const指针。
mutable 修饰符使得const函数的行为有了一些灵活性。相当于提醒编译器,这个成员变量比较特殊,不要进行任何只读检查了。
为什么 const 对象只能够调用const成员函数呢?,其实是这样的。由于对象本身通过 const 修饰,那么指向这个对象的指针也是指向const对象的const指针了。换句话说,指向这个对象的this指针是指向const对象的const指针。一般成员函数要求的this指针为:指向对象的const指针。所以此处发生了参数不匹配,无法进行调用。而 const 成员函数要求的this指针,恰恰是 指向const对象的const指针。所以依然能够调用。
八、const与函数
将函数的形参用const修饰是希望实参在函数内部不被修改,而一般函数接口可能会遇到以下三种情况:
1,const对象
2,指向const对象的指针
3,绑定const对象的引用
4,返回值是一个const对象
首先,我们看const对象的形参,这种接口用const修饰实际上没有任何意义,因为实参在传递给实参时是传递了一份副本,原实参是不会变化的。
1 int main(void)
2 {
3 int var = 42;
4 fun(var);
5 cout << var << endl; // print 42
6 return 0;
7 }
8 void fun( int i)
9 {
10 i = 10;
11 }
|
通过上面代码可以看出,实参如果只能过值进行传递,函数接口不用const修改,也不会令实参的值改变。
而通过指针或引用传递给函数时,函数可以通过形参来改变实参的值,这里如果需要对实参进行保护,则需要在函数接口声明形参为指向const类型的指针或引用。
而通过指针或引用传递给函数时,函数可以通过形参来改变实参的值,这里如果需要对实参进行保护,则需要在函数接口声明形参为指向const类型的指针或引用。
1 void fun( const int* p)
2 {
3 *p = 42; // error
4 int var = 10;
5 p = &var; // 可以改变p本身的值
6 }
7 void fun(const int& p)
8 {
9 p = 42; // error,p是一个指向const对象的引用
10 }
|
有的时候,我们需要函数的返回值是一个const对象,比如我们考虑一个有理数据类,我们给类定义了一个*的重载。
1 class Rational{
2 // ....
3 };
4 const Rational operator* (const Rational& lhs, const Rational& rhs);
5 Rational a, b, c;
6 a*b = c; // Error,因为左端为一个const对象
如果上面代码中重载操作符返回对象不是const类型,则a*b=c这个式子成立,实际上这与我们的内置类型的算术运算原则违背了,而我们希望我们设计的类的操作意义要像内置内类一样。
1 class Rational{
2 // ....
3 };
4 const Rational operator* (const Rational& lhs, const Rational& rhs);
5 Rational a, b, c;
6 a*b = c; // Error,因为左端为一个const对象
如果上面代码中重载操作符返回对象不是const类型,则a*b=c这个式子成立,实际上这与我们的内置类型的算术运算原则违背了,而我们希望我们设计的类的操作意义要像内置内类一样。
本文内容不用于商业目的,如涉及知识产权问题,请权利人联系SPASVO小编(021-61079698-8054),我们将立即处理,马上删除。