C++中的const到非常量转换
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7311041/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
const to Non-const Conversion in C++
提问by Shang Wang
I'm really annoyed by const
keyword these days, as I'm not quite familiar with it. I had a vector that stores all const pointers like vector<const BoxT<T> *> *Q_exclude
, and in the constructor of another class, I need an element in this queue to be passed in as a parameter and assign it to a non-const member. My question is:
const
这些天我真的对关键字很恼火,因为我不太熟悉它。我有一个存储所有常量指针的向量,例如vector<const BoxT<T> *> *Q_exclude
,并且在另一个类的构造函数中,我需要将此队列中的一个元素作为参数传入并将其分配给非常量成员。我的问题是:
How do I assign a const variable to a non-const variable? I know this doesn't make sense because after all, a const is a const, and should not be changed by any mean. But that annoying member variable REALLY has to be changed during the process! I might also change the data type in the vector to be non-const, but that would be too much work. Or does anyone know how to avoid such situation?
如何将常量变量分配给非常量变量?我知道这没有意义,因为毕竟,const 是一个 const,不应该以任何方式改变。但是那个烦人的成员变量真的必须在这个过程中改变!我也可能将向量中的数据类型更改为非常量,但这会带来太多工作。或者有谁知道如何避免这种情况?
回答by Lightness Races in Orbit
You can assign a const
object to a non-const
object just fine. Because you're copyingand thus creating a new object, const
ness is not violated.
您可以将const
对象分配给非const
对象就好了。因为您正在复制并因此创建一个新对象,const
所以不会违反 ness。
int main() {
const int a = 3;
int b = a;
}
It's differentif you want to obtain a pointer or reference tothe original, const
object:
如果您想获取指向原始对象的指针或引用,则情况有所不同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'
You can use const_cast
to hack around the type safety if you really must, but recall that you're doing exactly that: getting rid of the type safety. It's stillundefined to modify a
through b
in the below example:
const_cast
如果确实必须,您可以使用hack 来绕过类型安全,但请记住,您正在这样做:摆脱类型安全。它仍然不确定的修改a
通过b
在下面的例子:
int main() {
const int a = 3;
int& b = const_cast<int&>(a);
b = 3;
}
Although it compiles without errors, anything can happen including opening a black hole or transferring all your hard-earned savings into my bank account.
尽管它编译没有错误,但任何事情都可能发生,包括打开一个黑洞或将您辛苦赚来的所有积蓄转入我的银行账户。
If you have arrived at what you think is a requirement to do this, I'd urgently revisit your design because something is very wrong with it.
如果您已经达到了您认为执行此操作的要求,我会紧急重新审视您的设计,因为它有一些非常错误的地方。
回答by Alok Save
Changing a constant type will lead to an Undefined Behavior.
更改常量类型将导致Undefined Behavior。
However, if you have an originally non-const object which is pointed to by a pointer-to-const or referenced by a reference-to-const then you can use const_castto get rid of that const-ness.
但是,如果您有一个最初由指向常量的指针指向或由指向常量的引用引用的原始非常量对象,那么您可以使用const_cast来摆脱该常量。
Casting away constness is considered evil and should notbe avoided. You should consider changing the type of the pointers you use in vector to non-const if you want to modify the data through it.
虚掷常量性被认为是邪恶的,应该不会避免。如果您想通过它修改数据,您应该考虑将您在 vector 中使用的指针的类型更改为非常量。
回答by Jeremy Friesner
The actual code to cast away the const-ness of your pointer would be:
丢弃指针常量的实际代码是:
BoxT<T> * nonConstObj = const_cast<BoxT<T> *>(constObj);
But note that this really is cheating. A better solution would either be to figure out why you want to modify a const object, and redesign your code so you don't have to.... or remove the const declaration from your vector, if it turns out you don't really want those items to be read-only after all.
但请注意,这确实是作弊。更好的解决方案是弄清楚为什么要修改 const 对象,然后重新设计代码以便不必....毕竟真的希望这些项目是只读的。
回答by djg
void SomeClass::changeASettingAndCallAFunction() const {
someSetting = 0; //Can't do this
someFunctionThatUsesTheSetting();
}
Another solution is to call said function in-between making edits to variables that the const function uses. This idea was what solved my problem being as I was not inclined to change the signature of the function and had to use the "changeASettingAndCallAFunction" method as a mediator:
另一种解决方案是在对 const 函数使用的变量进行编辑之间调用所述函数。这个想法解决了我的问题,因为我不倾向于更改函数的签名并且不得不使用“changeASettingAndCallAFunction”方法作为中介:
When you call the function you can first make edits to the setting before the call, or (if you aren't inclined to mess with the invoking place) perhaps call the function where you need the change to the variable to be propagated (like in my case).
当您调用该函数时,您可以在调用之前首先对设置进行编辑,或者(如果您不想弄乱调用位置)也许可以在需要更改要传播的变量的地方调用该函数(例如我的情况)。
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();
}
Now, when some reference to "someFunctionThatUsesTheSetting" is invoked, it will invoke with the change to someSetting.
现在,当调用对“someFunctionThatUsesTheSetting”的某些引用时,它将随着对 someSetting 的更改而调用。