类的const成员函数的调用问题

Class A 
{
public:
    void f() {cout << i <<endl;}
private:
    int i = 0;
    //...
}; 
A a;
a.f();

类的成员函数有一个隐式的指针参数——this,this总是绑定到调用成员函数的对象,比如上面的a,即编译器会令this指针拥有a的地址。上面函数f要输出i的值,这个i是类对象a的数据成员i,这是通过this指针来实现的,相当于:

//伪代码,类成员函数相当于:
A::f(A* const this) //隐式参数写出来了
{ cout << this->i << endl;}
//a.f()这个调用相当于把a的地址赋给this:
A::f(&a);
//于是函数体中的语句执行变成:
cout << (&a)->i << endl;//输出的自然是a的i成员了

从上面可以看出this的默认类型是top-level const,即指向non-const类类型的const指针——A* const this;,于是我们不能令它指向一个const A类型对象,比如:

A* const this; //(用于演示)
const A ca;
this = &ca; //(用于演示)错误!ca是常量,不能绑定到指向非常量的指针
ca.f();    //所以这个调用就是错误的

为什么常量不能绑定到指向非常量的指针?因为如果可以这样做,我们就能通过指针改变常量的值!那常量的const属性也就无从谈起了:

//如果以上绑定合法
modify(*this);//ok,ca能算常量吗?

那类的常量对象比如ca它能调用什么样的成员函数呢?答案是只能调用const成员函数:

Class A 
{
public:
    void f() const  //常成员函数
    {cout << i <<endl;}
private:
    int i = 0;
    //...
};
const A ca;
ca.f();//这次调用合法了

因为常成员函数 void f() const;中的const的作用正是:修改隐式指针this使它具备low-level const属性,即this现在变为指向const的const指针——const A* const this;
而这个版本的this指针既可以指向常量类对象,又可以指向非常量类对象:

//用于演示:
const A* const this;
this = &a; //ok
//or
this = &ca; //ok

为什么一个非常量类对象能绑定到一个指向常量的指针呢?因为这种绑定是安全的,我们不能通过这个指针对对象进行任何写操作,从对象的角度看这个指针,是限制了对象本身的可变性,这种转换是令系统更稳定的一种转换,所以会被允许。
于是这样的调用:

//都合法
a.f();
ca.f();

总结:在对对象进行只读操作时,我们看到常成员函数具有更广泛的适用性,它既能被常量对象调用,又能被非常量对象调用,而且常量对象只能调用常成员函数,但是要对对象进行写操作,就必须使用非常的成员函数了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值