有什么理由喜欢static_cast<>超过C风格的演员吗?它们是等价的吗?他们有什么速度差异吗?
static_cast和reinterpret_cast似乎都可以很好地将void*转换为另一个指针类型.是否有充分理由支持其他人?
什么是一个相当于static_cast用boost::shared_ptr?
换句话说,我该如何重写以下内容
Base* b = new Derived();
Derived* d = static_cast<Derived*>(b);
Run Code Online (Sandbox Code Playgroud)
什么时候用shared_ptr?
boost::shared_ptr<Base> b(new Derived());
boost::shared_ptr<Derived> d = ???
Run Code Online (Sandbox Code Playgroud) 我有三个班:
class A {};
class B : virtual public A {};
class C : virtual public A {};
class D: public B, public C {};
Run Code Online (Sandbox Code Playgroud)
尝试从A*到B*的静态强制转换我得到以下错误:
cannot convert from base A to derived type B via virtual base A
Run Code Online (Sandbox Code Playgroud) 考虑以下代码(以及VirtualAlloc()返回avoid*的事实):
BYTE* pbNext = reinterpret_cast<BYTE*>(
VirtualAlloc(NULL, cbAlloc, MEM_COMMIT, PAGE_READWRITE));
Run Code Online (Sandbox Code Playgroud)
为什么reinterpret_cast选择而不是static_cast?
我以前认为reinterpret_cast可以用于例如从整数类型(例如DWORD_PTR)转换指针,但是从a转换void*为a BYTE*,是不是static_cast可以?
在这种特殊情况下是否存在任何(微妙的?)差异,或者它们是否只是有效的指针转换?
C++标准是否偏爱这种情况,建议采用一种方式而不是另一种方式?
显然,编译器认为它们是不相关的类型,因此reinterpret_cast是必需的.为什么这是规则?
说我想投A*,char*反之亦然,我们有两个选择(我的意思是,我们很多人认为我们有两个选择,因为两者似乎都有效!因此混乱!):
struct A
{
int age;
char name[128];
};
A a;
char *buffer = static_cast<char*>(static_cast<void*>(&a)); //choice 1
char *buffer = reinterpret_cast<char*>(&a); //choice 2
Run Code Online (Sandbox Code Playgroud)
两者都很好.
//convert back
A *pA = static_cast<A*>(static_cast<void*>(buffer)); //choice 1
A *pA = reinterpret_cast<A*>(buffer); //choice 2
Run Code Online (Sandbox Code Playgroud)
即便这样工作正常!
那么,为什么我们reinterpret_cast在C++中有两个链接 static_cast可以完成它的工作呢?
你们中的一些人可能认为这个主题与之前的主题重复,例如本文底部列出的,但事实并非如此.这些主题讨论只在理论上,但他们没有给出甚至一个例子来展示为什么reintepret_cast是真正需要的,而2 static_cast将肯定会失败.我同意,一个static_cast会失败.但两个怎么样?
如果两个链接的语法static_cast看起来很麻烦,那么我们可以编写一个函数模板,使其对程序员更友好:
template<class To, class From>
To any_cast(From v)
{
return static_cast<To>(static_cast<void*>(v));
}
Run Code Online (Sandbox Code Playgroud)
然后我们可以使用它,如:
char *buffer = any_cast<char*>(&a); …Run Code Online (Sandbox Code Playgroud) 请考虑以下代码:
struct Base {};
struct Derived : public virtual Base {};
void f()
{
Base* b = new Derived;
Derived* d = static_cast<Derived*>(b);
}
Run Code Online (Sandbox Code Playgroud)
这是标准([n3290: 5.2.9/2])禁止的,因此代码无法编译,因为Derived 实际上是继承自的Base.virtual从继承中删除使代码有效.
这条规则存在的技术原因是什么?
我刚刚在Qt中找到了以下代码,我对这里发生的事情感到有些困惑.
特别是对于什么reinterpret_cast<T>(0)呢?
template <class T>
inline T qobject_cast(const QObject *object)
{
// this will cause a compilation error if T is not const
register T ptr = static_cast<T>(object);
Q_UNUSED(ptr);
#if !defined(QT_NO_MEMBER_TEMPLATES) && !defined(QT_NO_QOBJECT_CHECK)
reinterpret_cast<T>(0)->qt_check_for_QOBJECT_macro(*reinterpret_cast<T>(const_cast<QObject *>(object)));
#endif
return static_cast<T>(const_cast<QObject *>(reinterpret_cast<T>(0)->staticMetaObject.cast(const_cast<QObject *>(object))));
}
Run Code Online (Sandbox Code Playgroud)
有人在乎解释吗?
根据[expr.cast]/4,C风格的强制转换按顺序尝试以下强制转换:
const_caststatic_caststatic_cast 其次是 const_castreinterpret_castreinterpret_cast 其次是 const_cast以下演员表格很好:
const_cast<int&>(static_cast<const int&>(0))
Run Code Online (Sandbox Code Playgroud)
然而,GCC和Clang都拒绝演员(int&)0.为什么?
c++ ×10
static-cast ×10
casting ×6
downcast ×2
pointers ×2
boost ×1
char ×1
const-cast ×1
qt ×1
shared-ptr ×1