問題描述
我一直聽到這種說法,雖然我實在找不到 const_cast 是邪惡的原因.
I keep hearing this statement, while I can't really find the reason why const_cast is evil.
在下面的例子中:
template <typename T>
void OscillatorToFieldTransformer<T>::setOscillator(const SysOscillatorBase<T> &src)
{
oscillatorSrc = const_cast<SysOscillatorBase<T>*>(&src);
}
我正在使用引用,并且通過使用 const,我可以保護我的引用不被更改.另一方面,如果我不使用 const_cast,代碼將無法編譯.為什么 const_cast 在這里會很糟糕?
I'm using a reference, and by using const, I'm protecting my reference from being changed. On the other hand, if I don't use const_cast, the code won't compile. Why would const_cast be bad here?
同樣適用于以下示例:
template <typename T>
void SysSystemBase<T>::addOscillator(const SysOscillatorBase<T> &src)
{
bool alreadyThere = 0;
for(unsigned long i = 0; i < oscillators.size(); i++)
{
if(&src == oscillators[i])
{
alreadyThere = 1;
break;
}
}
if(!alreadyThere)
{
oscillators.push_back(const_cast<SysOscillatorBase<T>*>(&src));
}
}
請給我提供一些例子,我可以從中看出使用 const_cast 是個壞主意/不專業.
Please provide me some examples, in which I can see how it's a bad idea/unprofessional to use a const_cast.
感謝您的任何努力:)
推薦答案
因為你在阻撓 const
的目的,是為了防止你修改參數.因此,如果你拋棄了某些東西的 const
性質,它就會毫無意義并且會使你的代碼變得臃腫,它會讓你違背你對函數用戶做出的不會修改參數的承諾.
Because you're thwarting the purpose of const
, which is to keep you from modifying the argument. So if you cast away the const
ness of something, it's pointless and bloating your code, and it lets you break promises that you made to the user of the function that you won't modify the argument.
此外,使用 const_cast
會導致未定義的行為.考慮這個代碼:
In addition, using const_cast
can cause undefined behaviour. Consider this code:
SysOscillatorBase<int> src;
const SysOscillatorBase<int> src2;
...
aFieldTransformer.setOscillator(src);
aFieldTransformer.setOscillator(src2);
在第一次通話中,一切都很好.你可以拋棄一個不是真正 const
的對象的 const
ness 并對其進行很好的修改.然而,在第二次調用中,在 setOscillator
中,您正在拋棄真正的 const
對象的 const
ness.如果你碰巧在那里的任何地方修改了那個對象,你就會通過修改一個真正是 const
的對象來導致未定義行為.由于您無法判斷標記為 const
的對象是否真的 const
聲明它的位置,因此您永遠不應該使用 const_cast
除非你確定你永遠不會改變對象.如果你不這樣做,那又有什么意義呢?
In the first call, all is well. You can cast away the const
ness of an object that is not really const
and modify it fine. However, in the second call, in setOscillator
you are casting away the const
ness of a truly const
object. If you ever happen to modify that object in there anywhere, you are causing undefined behaviour by modifying an object that really is const
. Since you can't tell whether an object marked const
is really const
where it was declared, you should just never use const_cast
unless you are sure you'll never ever mutate the object ever. And if you won't, what's the point?
在您的示例代碼中,您存儲了一個指向可能是 const
的對象的非 const
指針,這表明您打算改變該對象(否則為什么不只是存儲一個指向 const
的指針?).這可能會導致未定義的行為.
In your example code, you're storing a non-const
pointer to an object that might be const
, which indicates you intend to mutate the object (else why not just store a pointer to const
?). That might cause undefined behaviour.
另外,這樣做可以讓人們向您的函數傳遞一個臨時變量:
Also, doing it that way lets people pass a temporary to your function:
blah.setOscillator(SysOscillatorBase<int>()); // compiles
然后您將存儲一個指向臨時對象的指針,當函數返回1時該指針將無效.如果您采用非const
引用,則不會遇到此問題.
And then you're storing a pointer to a temporary which will be invalid when the function returns1. You don't have this problem if you take a non-const
reference.
另一方面,如果我不使用 const_cast,代碼將無法編譯.
On the other hand, if I don't use const_cast, the code won't compile.
然后更改您的代碼,不要添加演員表以使其工作.編譯器沒有編譯它是有原因的.現在您知道原因了,您可以讓 vector
指向 const
的指針,而不是將一個方孔變成圓形以適合您的掛鉤.
Then change your code, don't add a cast to make it work. The compiler is not compiling it for a reason. Now that you know the reasons, you can make your vector
hold pointers to const
instead of casting a square hole into a round one to fit your peg.
因此,在所有情況下,最好讓您的方法接受非 const
引用,而使用 const_cast
幾乎從來都不是一個好主意.
So, all around, it would be better to just have your method accept a non-const
reference instead, and using const_cast
is almost never a good idea.
1 實際上是在調用函數的表達式結束時.
1 Actually when the expression in which the function was called ends.
這篇關于C++:為什么 const_cast 是邪惡的?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!