新手问题:c ++ const到非const转换

时间:2011-09-05 17:18:58

标签: c++ const

这些天我对const关键字非常恼火,因为我对它并不熟悉。我有一个存储所有const指针的向量,如vector<const BoxT<T> *> *Q_exclude,并且在另一个类的构造函数中,我需要将此队列中的一个元素作为参数传入并将其分配给非const成员。我的问题是:

如何将const变量赋值给非const变量?我知道这没有意义,因为毕竟const是一个const,不应该被改变。但是在这个过程中必须改变那个恼人的成员变量REALLY!我也可能会将向量中的数据类型更改为非const,但这样做太多了。或者有谁知道如何避免这种情况?

5 个答案:

答案 0 :(得分:72)

您可以将const对象分配给非const对象。因为您正在复制并因此创建新对象,所以不会违反const

Like so:

int main() {
   const int a = 3;
   int b = a;
}

It's different如果您想获取指针或引用 原始const对象:

int main() {
   const int a = 3;
   int& b = a;       // or int* b = &a;
}

//  error: invalid initialization of reference of type 'int&' from
//         expression of type 'const int'

如果你真的必须使用const_cast来破解类型安全,但请记住你正是这样做的:摆脱类型安全。在the below example中修改ab仍然未定义:

int main() {
   const int a = 3;
   int& b = const_cast<int&>(a);

   b = 3;
}

虽然编译没有错误,但任何事情都可能发生,包括打开黑洞或将所有来之不易的积蓄转入我的银行账户。

如果你已经达到了你认为要做到这一点的要求,我会紧急重新审视你的设计,因为它有一些非常错误。

答案 1 :(得分:7)

更改常量类型将导致未定义行为

但是,如果你有一个最初的非const对象,它由指向const的指针指向或由引用指向const引用,那么你可以使用 const_cast 来摆脱那个常数。

抛弃常量被认为是邪恶的,应该避免 而不是 。如果要通过它修改数据,则应考虑将在vector中使用的指针类型更改为非const。

答案 2 :(得分:3)

抛弃指针常量的实际代码是:

BoxT<T> * nonConstObj = const_cast<BoxT<T> *>(constObj);

但请注意,这确实是在作弊。一个更好的解决方案是找出你想要修改const对象的原因,并重新设计你的代码,这样你就不必....或者从你的向量中删除const声明,如果事实证明你没有真的希望那些项目毕竟是只读的。

答案 3 :(得分:0)

void SomeClass::changeASettingAndCallAFunction() const {
    someSetting = 0; //Can't do this
    someFunctionThatUsesTheSetting();
}

另一种解决方案是在对const函数使用的变量进行编辑之间调用该函数。这个想法解决了我的问题,因为我不愿意更改函数的签名,而不得不使用“ changeASettingAndCallAFunction”方法作为调解器:

调用该函数时,您可以先在调用之前对设置进行编辑,或者(如果您不希望弄乱调用位置)可能在需要更改要传播的变量的地方调用该函数(例如我的情况)。

void SomeClass::someFunctionThatUsesTheSetting() const {
     //We really don't want to touch this functions implementation
     ClassUsesSetting* classUsesSetting = ClassUsesSetting::PropagateAcrossClass(someSetting);
     /*
         Do important stuff
     */
}

void SomeClass::changeASettingAndCallAFunction() const {
     someFunctionThatUsesTheSetting();
     /*
         Have to do this
     */
}

void SomeClass::nonConstInvoker(){
    someSetting = 0;
    changeASettingAndCallAFunction();
}

现在,当调用对“ someFunctionThatUsesTheSetting”的某些引用时,它将以对someSetting的更改来调用。

答案 4 :(得分:0)

这个留给我自己

如果遇到此错误,应该在使用const char*时使用char* const

这使指针恒定,而不是字符串的内容。

const char* const使它的值和指针也保持不变。