zoukankan      html  css  js  c++  java
  • 类4(可变数据成员/基于const的重载)

    可变数据成员:

    有时我们希望能修改某个类的数据成员,即使是在一个 const 成员函数内。可以通过在变量的声明中加入 mutable 关键字来声明一个可变数据成员。mutable 是为突破 const 的限制而设置的。被 mutable 修饰的变量将永远处于可变状态中,即使是在一个 const 成员函数中:

     1 #include <iostream>
     2 using namespace std;
     3 
     4 class gel{
     5 private:
     6     mutable size_t access_ctr;
     7 
     8 public:
     9     gel() = default;
    10     gel(const int &x):access_ctr(x){}
    11     // ~gel();
    12 
    13     void out_put() const{
    14         cout << access_ctr << endl;
    15     }
    16 
    17     void some_member(void) const{
    18         ++access_ctr;
    19     }
    20 };
    21 
    23 int main(void){
    24     const gel x(1);
    25     x.out_put();//输出1
    26     x.some_member();
    27     x.out_put();//输出2
    28     x.some_member();
    29     x.out_put();//输出3
    30     return 0;
    31 }

    关于 mutable 关键字存在的必要性:https://www.zhihu.com/question/64969053/answer/226383958

    基于 const 的重载:

     1 #include <iostream>
     2 using namespace std;
     3 
     4 class gel{
     5 private:
     6     int x;
     7 
     8 public:
     9     gel() = default;
    10     gel(int val): x(val){}
    11 
    12     const gel &display(std::ostream &os) const{
    13         std::cout << x;
    14         return *this;
    15     }
    16 
    17     gel &count(void){
    18         x++;
    19         return *this;
    20     }
    21 };
    22 
    23 int main(void){
    24     gel x(0);
    25     x.display(cout);
    26     x.count();
    27     // x.display(cout).count();//错误:display 返回的是一个 const 对象,而 count 不是常量函数
    28     return 0;
    29 }

    一般来说像 x.display(cout); 与 x.count(); 应该是要可以写成 x.display(cout).count();的形式的。但这个代码中 display 返回的是一个 const 对象,所以后者显然是错误的。这是我们代码写的不合理,应该尽量避免写出这样的代码。我们可以通过重载解决这个问题:

     1 #include <iostream>
     2 using namespace std;
     3 
     4 class gel{
     5 private:
     6     int x;
     7 
     8 public:
     9     gel() = default;
    10     gel(int val): x(val){}
    11 
    12     gel &display(std::ostream &os){
    13         do_display(os);
    14         // os << x;//在代码比较短的时候这样写也一样,不过要是代码量大的话显然要多写不少代码
    15         return *this;
    16     }
    17 
    18     const gel &display(std::ostream &os) const{
    19         do_display(os);
    20         // os << x;
    21         return *this;
    22     }
    23 
    24     gel &count(void){
    25         x++;
    26         return *this;
    27     }
    28 
    29 private:
    30     void do_display(std::ostream &os) const{
    31         os << x;
    32     }
    33 };
    34 
    35 int main(void){
    36     gel x(0);
    37     x.display(cout).count();
    38     return 0;
    39 }

    这里我们通过调用 display 的对象是否为常量来决定调用哪个 display 函数。需要注意的是这里是通过底层 const 来区分重载函数的(形参会忽略顶层 const),若调用 display 的对象是 const,那么隐式传递的 this 指针具有底层 const,反之则没有。

    调用 display 的是非常量的话,display 返回的也是一个非常量对象,此时 x.display(cout).count();顺利执行;

    调用 display 的是常量的话, display 返回的也是一个常量对象,此时 x.display(cout).count();报错。

    显然,这个代码中的 x.display(cout).count();与 x.display(cout);x.count();是完全等价的。

  • 相关阅读:
    Vue Cli3.0 使用jquery
    使用js加载器动态加载外部js、css文件
    通过js获取本机的IP地址
    $.ajax 中的contentType类型
    vue中 :style 与 :class 三元运算符使用
    bootstrap table checkbox获得选中得数据
    vscode自动生成文件头部注释和函数注释
    axios二次封装的几种方法
    vue组件库element-ui 的Table内容显示不更新
    Linux中iptables设置详细
  • 原文地址:https://www.cnblogs.com/geloutingyu/p/8087928.html
Copyright © 2011-2022 走看看