const普遍用法 const对象、const成员函数、mutable类型

[复制链接]

1234

主题

-8

回帖

216

积分

游客

积分
216
a420995601 发表于 2018-12-23 02:02:28 | 显示全部楼层 |阅读模式
  const普遍用法 const对象、const成员函数、mutable类型
  先来总结一下const的一些普遍用法:
  1 可以用来定义常量,称为const常量
  const int x = 100;
  2 用来修饰引用,称为const引用,表明不能修改引用所引用的变量的值
  const int &ref = x;
  int &ref2 = x; //Error, ref2不是常量,可以修改引用所指向的变量x的值,而x实际上是常量,不允许修改,故不合逻辑,这种用法是错误的
  3 用来修饰指针,有三种情况
  第一种,const出现在*左边,表示(*指针)是常量,而指针是变量,可以指向其它变量,如下:
  const int *p;
  第二种,const 出现在*右边,表示指针是常量,指针不能指向其它变量,但是可以改变指针指向的变量的内容,如下:
  int *const p = &x;
  第三种,const既在*左边,也在*右边,表明指针是常量,指针所指向的变量的内容也是常量,如下:
  const int *const p = &x;
  4 用来修饰类中的数据成员,称之为const数据成员,const数据成员的初始化要在构造函数的初始化列表中进行。不能在数据成员定义时直接初始化。
  5 用来修饰类对象,称为const对象
  const Test t(10);
  6 用来修饰类中的成员函数,称之为const成员函数,表示该函数不能修改对象的状态,也就是说它只能访问数据成员(Read Only),而不能修改数据成员。
  上面已经将const的所有用法进行了总结回顾,这里再分析一下,当const用来修饰类中的成员函数时,它不能修改类中的数据成员,但是在某些场合,它还是需要修改类的的某些数据成员时,该怎么办呢?这时候mutable类型的作用就发挥出来了,mutable的英文名是可变的,易变的,即由它修饰后的数据成员,无论是在const成员函数,还是非const成员函数均可以访问它,当然,除了static静态成员函数外(因为静态成员函数没有this指针,不能访问对象数据成员及函数)。这样一来,const成员函数就不能修改类中的非mutable修饰的数据成员,对这些数据成员只能是read only,但是却可以read/write那些由mutable修饰的数据成员了。捕鱼游戏 星力捕鱼 在某些应用场合是比较灵活的。下面就举个简单的例子说明这些问题:
  #include
  using namespace std;
  class Test
  {
  public:
  Test(int x):x_(x), outputTimes_(0)
  {
  }
  //因为Getx()这个成员函数不会去更改x数据成员,所以用const修饰,称之为const成员函数,它不能去修改数据成员的值
  int Getx() const
  {
  //x_ = 100 ;// Error, const成员函数不能修改数据成员的值
  cout << "const Getx..."<< endl;
  return x_;
  }
  //非const成员函数与上面const成员函数构成重载
  int Getx() //非const与const成员函数是可以构成重载的
  {
  cout << "Getx..."<<endl; </endl;
  return x_;
  }
  int Setx()
  {
  return x_;
  }
  void Output() const
  {
  //x_ = 102; //Error,不能修改非mutable数据成员
  cout << "x = "<< x_ << endl;
  outputTimes_++; //可以修改mutable类型的数据成员
  }
  int GetOutputTimes() const
  {
  return outputTimes_;
  }
  private:
  int x_;
  mutable int outputTimes_; //mutable数据成员
  };
  int main()
  {
  //const对象,对象是常量,对象的状态不能更改,声明时要初始化
  const Test t(10);
  t.Getx(); //前提:若int Getx() const注释掉,则const对象是不能调用非const的Getx()成员函数的
  //t.Setx(); //Error,理由同上,即const对象只能调用const成员函数,理由是:const对象是常量,对象的状态是不允许更改的,而非const即普通成员函数可以更改对象的状态,这所以为了实现不允许修改对象的状态这一目的,const对象禁止调用非const成员函数,而只能调用const成员函数,因为const成员函数也是禁止修改数据成员的,符合这一目的。
  Test t2(20);
  t2.Getx(); //调用的是非const的Getx,因为t2是普通对象,不是const对象
  t2.Output(); //普通对象可以调用const成员函数,如果有重载的非const成员函数,则调用的是非const的成员函数
  t2.Output(); //每输出一次,outputTimes_加1,因为它是mutable类型的数据成员,允许在const成员函数中被修改
  cout << "outputTimes= "<< t2.GetOutputTimes() << endl;
  return 0;
  }
  这里需要注意的是const对象由于不能修改对象的状态,const对象只能调用const成员函数,而普通对象可以调用任何的成员函数。此外const对象在声明时要进行初始化。这与const修改的变量是一致的,如const int x = 100; 当类中定义了2个同名称的函数,其中一个用const修饰,另一个没有const修饰,他们之间是构成重载的,这时const对象调用的是const成员函数,而普通对象调用的是非const成员函数。

你喜欢看
  • python如何操作Sql Server 2008

      python如何操作Sql Server 2008   最近由于公司的一个项目需要,需要使用Sql Server 2008数据库,开 ...

  • linux内核如何管理进程

      linux内核如何管理进程   “进程”有诸多的定义,在许多的教材资料上,其定义是一个程序的执行实例, ...