C ++:为什么const_cast邪恶? [英] C++: Why is const_cast evil?

查看:180
本文介绍了C ++:为什么const_cast邪恶?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



在下面的例子中:

  template< typename T> 
void OscillatorToFieldTransformer< T> :: setOscillator(const SysOscillatorBase< T& src)
{
oscillatorSrc = const_cast< SysOscillatorBase *>(& src)
}



我使用的是引用,通过使用const,我的参考从改变。另一方面,如果我不使用const_cast,代码将无法编译。为什么const_cast在这里不好?



这同样适用于以下示例:

  template< typename T> 
void SysSystemBase< T> :: addOscillator(const SysOscillatorBase< T& src)
{
bool alreadyThere = 0;
for(unsigned long i = 0; i< oscillatorators.size(); i ++)
{
if(& src == oscillatorators [i])
{
alreadyThere = 1;
break;
}
}
if(!alreadyThere)
{
oscillatorators.push_back(const_cast< SysOscillatorBase< T&
}
}

请提供一些示例,



感谢您的努力:)

使用const_cast是个不好的主意/不专业。解决方案

因为你挫败了 const 的目的,其中是阻止你修改参数。所以如果你抛弃了一些东西的 const ,它是无意义和膨胀你的代码,它允许你打破你对你赢得的函数的用户的承诺,



此外,使用 const_cast 可能会导致未定义的行为。请考虑以下代码:

  SysOscillatorBase< int> src; 
const SysOscillatorBase< int> src2;

...

aFieldTransformer.setOscillator(src);
aFieldTransformer.setOscillator(src2);

在第一次调用中,一切正常。你可以抛弃一个不真正 const 的对象的 const ,并修改它。然而,在第二次调用中,在 setOscillator 中,你抛弃了一个真正 const > const 对象。如果你碰巧在那里修改那个对象,你通过修改一个实际上是 const 的对象会导致未定义的行为。因为你无法判断标记为 const 的对象是否真的 const 声明,你应该永远不要使用 const_cast ,除非你确信你永远不会改变对象。



在您的示例代码中,您将存储一个非< - const 指向可能是 const 的对象的指针,这表示您打算对对象进行变异(为什么不只是存储一个指向 const ?)。这可能会导致未定义的行为。



,这样做让人们通过一个临时到你的函数:

  blah.setOscillator(SysOscillatorBase< int>()); // compiles 

然后你存储一个指向临时的指针,当函数返回 1 。如果您使用非< - const 引用,则没有此问题。


另一方面,如果我不使用const_cast,代码将不会编译。


然后更改你的代码,don不要添加一个强制转换,使其工作。编译器没有编译它的原因。现在你知道原因,你可以让向量保存指向 const 的指针,而不是在



所以,四周,最好是让你的方法接受一个非< - const 引用,而使用 const_cast 几乎从不是一个好主意。






1 实际上当调用函数的表达式结束时。


I keep hearing this statement, while I can't really find the reason why const_cast is evil.

In the following example:

template <typename T>
void OscillatorToFieldTransformer<T>::setOscillator(const SysOscillatorBase<T> &src)
{
    oscillatorSrc = const_cast<SysOscillatorBase<T>*>(&src);
}

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?

The same applies to the following example:

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));
    }
}

Please provide me some examples, in which I can see how it's a bad idea/unprofessional to use a const_cast.

Thank you for any efforts :)

解决方案

Because you're thwarting the purpose of const, which is to keep you from modifying the argument. So if you cast away the constness 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.

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);

In the first call, all is well. You can cast away the constness of an object that is not really const and modify it fine. However, in the second call, in setOscillator you are casting away the constness 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?

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

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.

On the other hand, if I don't use const_cast, the code won't compile.

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.

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 Actually when the expression in which the function was called ends.

这篇关于C ++:为什么const_cast邪恶?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆