类的const成员函数

来源:互联网 发布:vendor.bundle.js 位置 编辑:程序博客网 时间:2024/05/14 06:05

类的const成员函数

class Sales_data{public:    string Get_isbn() const {return bookNo;}    //const成员函数pritvate:    string bookNo;};

定义为const的成员函数 不可以修改类的数据成员(只读)
在成员函数内使用类的数据成员时,实际上隐式的引入了 this

//以上面的Get_isbn()为例string Get_isbn() const {return this->bookNo;}//等价于上面的写法

而紧随参数表之后的const关键字,作用是修改隐式this指针的类型为常量指针


返回*this的成员函数

可以让成员函数返回*this来将调用它的对象返回

class Screen{public:    Screen &Move(int x,int y)    {        //省略函数实现        return *this;              }    Screen &Show()    {        //省略实现        return *this;    }};Screen sc;sc.Move(1,2).Show();        

从const成员函数返回*this

const成员函数通过*this返回的是常量

const Screen &Display() const {    //省略实现      return *this;}//返回类型的const不可省略

这样设置其实是很有道理的,试想,将一个成员函数设置为const,目的就是禁止该成员函数修改类内数据成员,使其返回常量(引用)可以禁止间接的修改数据成员。


但这引入了一个新的问题:
一个非常量对象调用了const成员函数后会变成一个常量对象(函数返回引用时为常量引用)

//a exampleclass A{public:    A &Set(int x)    {        val = x;        return *this;    }    const A &Read() const          //一个const成员函数,返回const引用(底层)    {        cout<<val<<endl;        return *this;    }private:    int val;};A obj;obj.Set(5).Read().Set(3);       //ERROR 调用Read()后返回常量引用

为了解决这个问题,我们可以写一个重载,根据调用成员函数的对象本身是常量或非常量来决定调用哪个版本

class Screen{public:    Screen &display(std::ostream &os)    {        do_display(os);        cout<<"1"<<endl;        return *this;    }    const Screen &display(std::ostream &os) const    {        do_display(os);        cout<<"2"<<endl;        return *this;    }private:    string contents = "test";    void do_display(std::ostream &os) const    {        os<<contents<<endl;              //将“只读”模块封装    }}    Screen obj;                   //非常量对象    const Screen cobj;            //常量对象(只可以调用常量成员函数)    obj.display(cout);            //调用非常量版本    cobj.display(cout);           //调用常量版本

这与我们之前所了解的重载有点不同,函数重载是通过参数表来区分的
而这里的常量与非常量成员函数的重载区分依据是调用他们的对象是常量还是非常量


可变数据成员mutable

一个可变数据成员,永远不会是const
无论是在const对象中还是在const成员函数中都可以修改

class Screen{public:    void func() const    {        x = 10;             //即使在const成员函数中也可以修改mutable变量的值     }    void Show()     {        cout << x << endl;    }private:    mutable int x = 0;};

类的常量对象

用const关键字来定义一个类的常量对象

对于类的函数成员: 常量对象只能访问常量函数成员
对于类的数据成员: 常量对象可以访问数据成员,但不能修改
对于mutable数据成员: 常量对象既可以访问也可以修改

class A{public:    mutable int val;    int a;    A(int _val,int _a):val(_val),a(_a) {}    A& Set(int _val,int _a)    {        val = _val;        a = _a;    }    const A& Read() const            //常量函数成员    {        cout << val << endl            << a << endl;        return *this;    }};const A a(5,10);        //定义一个类的常量对象a.Read();               //oka.Set(1,2);             //error! a只可以访问常量函数成员a.val = 999;            //ok  常量对象可以改变mutable数据成员a.a = 999;              //error! 对于普通数据成员,常量对象只能访问不可以修改
原创粉丝点击