是static_cast滥用吗? [英] Is static_cast misused?

查看:951
本文介绍了是static_cast滥用吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对 static_cast 有不同的感觉,因为它是最安全的C ++强制转换,但同时允许安全和不安全的转换,因此您必须知道上下文来说,如果它实际上是安全的或可能导致UB(例如,当转换到子类)。



那么为什么没有一个更安全的显式转换?这里是一个例子,它可能是有用的。在COM中,他们必须返回接口指针 void ** ppv ,因此必须显式处理

  * ppv =(IInterface *)this; 

然后建议用更安全的C ++代码替换

  * ppv = static_cast< IInterface *>(this); 

但是做一个 static_cast 这里? 这个是从 IInterface 派生的类,因此可以写成

  IInterface * p = this; //隐式转换为base,确保
* ppv = p;

或使用类似

的帮助器

  template< class T,class U> 
T implicit_cast(U p){return p; }

* ppv = implicit_cast< IInterface *>(this);

因此, static_cast 有时会被滥用,并且在某些情况下可以(应该?)被这个 implicit_cast 替换?



编辑:我知道在COM中需要转换,但是它不必是 static_cast ,隐式转换就足够了。

在这种特殊情况下,我相信总是知道投射将向上,因此 static_cast 完全安全。



看起来使用你的 implicit_cast 可能会更安全,



我用g ++和 implicit_cast 确实按照预期返回不同基类的不同地址。



但请注意,对于你的第一句话,我会认为 dynamic_cast 实际上比 static_cast 更安全,因为如果无法完成转换,它将返回null或throw。相反, static_cast 会返回一个有效的指针,让你继续前进,直到你的程序在未来的某个时候爆炸, p>

测试程式:

  #include< iostream> 

class B1
{
public:
virtual〜B1(){}
};

class B2
{
public:
virtual〜B2(){}
};

class Foo:public B1,public B2
{
};

template< class T,class U>
T implicit_cast(U p){return p; }

int main()
{
Foo * f = new Foo;
void ** ppv = new void *;

* ppv = implicit_cast< B1 *>(f);
std :: cout<< * ppv < std :: endl ;;
* ppv = implicit_cast< B2 *>(f);
std :: cout<< * ppv < std :: endl ;;

return 0;
}


I have mixed feelings about static_cast, as it is the safest C++ cast available, but allows both safe and unsafe conversions at the same time, so you have to know the context to say if it is actually safe or might lead to UB (e.g. when casting to a sub-class).

So why isn't there a safer explicit cast? Here is an example, where it could be useful. In COM, they have to return the interface pointer as void** ppv, so "have to" cast explicitely

*ppv = (IInterface*) this;

which was then suggested to be replaced by a safer C++ cast

*ppv = static_cast<IInterface*>(this);

But does it make sense to make even a static_cast here? this is of a class which derives from IInterface, so one could simply write

IInterface* p = this; // implicit conversion to base, safe for sure
*ppv = p;

or use a helper like

template<class T, class U>
T implicit_cast(U p) { return p; }

*ppv = implicit_cast<IInterface*>(this);

So, is it true that static_cast is sometimes misused and can (should?) be replaced by this implicit_cast in some cases, or am I missing something?

EDIT: I know that a cast is required in COM, but it does not have to be static_cast, an implicit cast would be enough.

解决方案

In this particular case I believe that it's always known that the casting will be upwards and that therefore static_cast should be perfectly safe.

It does appear that using your implicit_cast would probably be safer, and allows you to explicitly pick which base class you want to implicitly cast to (which is apparently required for COM).

I did a quick test with g++ and implicit_cast does indeed return different addresses for different base classes as expected.

Do note however that in regards to your very first sentence I would argue that dynamic_cast is in fact safer than static_cast since it will return null or throw if the cast can't be completed. In contrast, static_cast will return a valid-looking pointer and let you keep going until your program blows up at some time in the future, unconnected to the original bad cast.

Test program:

#include <iostream>

class B1
{
public:
    virtual ~B1() {}
};

class B2
{
public:
    virtual ~B2() {}
};

class Foo : public B1, public B2
{
};

template<class T, class U>
T implicit_cast(U p) { return p; }

int main()
{
    Foo* f = new Foo;
    void **ppv = new void*;

    *ppv = implicit_cast<B1*>(f);
    std::cout << *ppv << std::endl;;
    *ppv = implicit_cast<B2*>(f);
    std::cout << *ppv << std::endl;;

    return 0;
}

这篇关于是static_cast滥用吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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