const_cast VS可变?任何差异

const_cast VS mutable ? any difference?

本文关键字:任何差 可变 VS cast const      更新时间:2023-10-16

根据我的理解,mutable取消了变量的constness

Class A {
  void foo() const {
  m_a = 5;
}
mutable int m_a;
};

还有const_cast:

void print (char * str)
{
  cout << str << endl;
}
int main () {
  const char * c = "this is a line";
  print ( const_cast<char *> (c) );
  return 0;
}

那么,是什么改变了一个和另一个?

感谢

const_cast无法取消对象的常量。const_cast只能从对象的访问路径中移除常量。访问路径是指向对象的指针或引用。从访问路径中删除常量对对象本身绝对没有影响。即使使用const_cast来删除访问路径的常量,也不一定授予您修改对象的权限。能否做到这一点仍然取决于对象本身。如果它是const,则不允许修改它,并且任何这样做的尝试都将导致未定义的行为。

例如,这说明了const_cast 的预期用途

  int i = 5; // non-constant object
  const int *p = &i; // `p` is a const access path to `i`
  // Since we know that `i` is not a const, we can remove constness...
  int *q = const_cast<int *>(p);
  // ... and legally modify `i`
  *q = 10;
  // Now `i` is 10

上述内容合法有效的唯一原因是i实际上是一个非常数对象,我们对此有所了解

如果原始对象真的是常量,那么上面的代码将产生未定义的行为:

  const int j = 5; // constant object
  const int *p = &j; // `p` is a const access path to `j`
  int *q = const_cast<int *>(p); // `q` is a non-const access path to `j`
  *q = 10; // UNDEFINED BEHAVIOR !!!

C++语言不允许您修改常量对象,const_cast在这里完全无能为力,无论您如何使用它

mutable则完全不同。mutable创建一个数据文件,即使包含的对象被声明为const,该文件也可以合法修改。从这个意义上说,mutable确实允许您修改常量对象的[某些指定部分]。另一方面,const_cast不能做那样的事情。

区别在于const_cast不能作弊,但mutable是规则的例外。

在第一个代码段中,m_amutable,因此是不能修改const成员函数上的数据成员的规则的例外。

在第二个片段中,const_cast试图作弊,但确实不能:虽然类型已经更改,但不允许实际修改:字符串确实是const。试图修改它会导致程序表现出未定义的行为。

不同之处在于语义,即生成的代码相同,运行时结果相同(无论如何,constness是一个纯粹的编译时构造),但这两个构造传达的含义略有不同。

其思想是对类中的变量使用mutable,但不构成对象的状态。经典示例是blob对象中的当前位置。在blob中导航并不算作以重要的方式"修改"blob。使用mutable,表示"此变量可能会更改,但对象仍然相同"。您指出,对于这个特定的类,const-ness并不意味着"所有变量都被冻结"。

另一方面,const_cast意味着你违反了现有的const正确性,并希望逃脱惩罚。可能是因为你使用的是不尊重const的第三方API(例如,基于C的老式API)。

简单地说,将成员变量声明为mutable使其可以从该类的任何常量方法进行写访问,而无需任何其他特殊语法。另一方面,每当您想要对一个常量变量进行写访问时,就必须执行const_cast,而且该变量甚至不必是类成员。

除非您想明确允许对成员变量进行写访问,否则在所有违反常量正确性的情况下,如果只是为了清楚地说明您的意图,则最好使用const_cast

附带说明一下,const_cast也可以用于添加或删除volatile修饰符。