2012-07-12 92 views
8

从我的理解,mutable取消的变量const_cast VS可变吗?有什么区别?

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

constness但也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; 
} 

那么,什么样的变化从另一个?

谢谢

回答

16

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不能做那样的事情。

1

区别是语义 - 我。即相同的生成代码,相同的运行时结果(const ness纯粹是编译时构造),但这两个构造表达的意思稍有不同。

这个想法是,你使用mutable为类中的变量,但不构成对象的状态。经典示例是blob对象中的当前位置。在blob中导航不会被视为以重要的方式“修改”blob。通过使用mutable,你说“这个变量可能会改变,但对象仍然是一样的”。你说的是,对于这个特定的班级,const-并不意味着“所有变量都被冻结”。

const_cast从另一方面来说,意味着你违反了现有的const正确性,并希望摆脱它。可能是因为您正在使用不尊重const(例如,一所以前的C语言课程)的第三方API。

4

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

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

在第二个片段,const_cast试图欺骗,但真的不能:虽然类型发生了变化,实际的修改是不允许:字符串是真正const。试图修改它会导致程序出现未定义的行为。

0

简单地说,声明一个成员变量为mutable使得它可以通过该类的任何常量方法进行写入访问,而无需任何其他特殊语法。另一方面需要执行另一个变量const_cast,只要你想写访问一个常数变量,并且该变量甚至不必是类成员。

除非你想显式地允许对成员变量的写入权限,否则在每一个违反const正确性的情况下使用const_cast都是首选的,如果只是为了清楚说明你的意图。

在附注上,const_cast也可用于添加或删除volatile修饰符。

相关问题