我需要转换的一个组成型,其中包含一个地址,实际指针的类型。我可以用reinterpret_cast如下:

MyClass *mc1 = reinterpret_cast<MyClass*>(the_integer);

然而,这并不执行任何运行时查看如果地址在问题实际上拥有MyClass对象。我想知道如果有任何好处,在第一个转换为一个void*(使用reinterpret_cast)和随后使用dynamic_cast的结果。是这样的:

void *p = reinterpret_cast<void*>(the_integer);
MyClass *mc1 = dynamic_cast<MyClass*>(p);
assert(mc1 != NULL);

是否有任何优势,在使用第二种方法?

有帮助吗?

解决方案

类型上dynamic_cast检查由不同的C ++实现不同的方式实现;如果你想为你的具体实现的答案,你应该提到你使用的是什么实现。回答一般问题的唯一方法是指ISO标准C ++。

通过我的标准的读出,在一个空指针调用dynamic_cast是非法的:

dynamic_cast<T>(v)
  

“如果T是一个指针型,V应的指针的右值来完成类类型”

(来自ISO C ++标准的5.2.7.2)。 void不是一个完整的类型,所以表达式是不合法的。

有趣的是,类型被铸造允许是一个空指针,即

void * foo = dynamic_cast<void *>(some_pointer);

在这种情况下,dynamic_cast总是成功,将所得的值是一个指向最派生的对象通过v指向。

其他提示

没有,有没有具体的优势,在这样做。您使用reinterpret_cast的那一刻,所有的赌注都关闭。它是由你来确保演员是有效的。

实际上没有严重的优势。如果无效*点的东西,是不是一个指向多态对象,你遇到不确定的行为(通常是访问冲突)马上。

在安全的方式是保持所有活MyClass的对象的记录。最好是保持这个纪录在std::set<void*>,这意味着你可以轻松地添加,删除和测试的元素。

之所以将它们存储为void*s是,你不要冒险nastyness喜欢从你的整数创建未对齐MyClass*指针。

  • 首先"诠释" intvoid * 是个坏主意。如果 sizeof(int) 4和 sizeof(void *) 8(64系统)它虐待形成的。

  • 而且 dynamic_cast 是有效的情况下,多晶型的课程。

选项1是唯一的(半)便携式/有效的选项。

选项2:无效C ++作为dynamic_cast的(如空隙是不允许的)

目前的实现水平它需要从源类型的类型信息来获得到目标类型。没有办法(或者有可能是没有办法),以获得从空隙运行时源类型信息*所以这不是有效的任一。

的dynamic_cast用于到CAS上下类型层次不从未知类型。

作为一个侧面说明,你或许应该使用void *的,而不是一个整数存储一个无类型指针。有潜力的一个int不是大到足以存储一个指针。

最安全的方式来处理指针在C++是处理他们的类型安全的。这意味着:

  • 从来没有存储指在其他任何东西比一个指
  • 避免无效的指针
  • 从来没有通过的指针为其他进程
  • 考虑weak_ptr如果计划使用的指针在线程

为此原因是:什么你打算要做的就是不安全的和可以避免,除非你在与不安全的(传统?) 代码。在这种情况下考虑MSalters'的答案,但要注意,它仍然是一个麻烦。

如果你确实知道the_integer点到一个已知的基类(即具有至少一个虚拟构件),有可能实际上是一个优势:知道该对象是一个特定的派生类的。但是你不得不reinterpret_cast到你的基类,然后再做dynamic_cast

BaseClass* obj = reinterpret_cast<BaseClass*>(the_integer);
MyClass* myObj = dynamic_cast<BaseClass*>(obj);

void*使用dynamic_cast是无用的,完全错误的。不能使用dynamic_cast检查是否有在存储一些任意位置的有效对象。

您也应该在非指针类型变量的存储地址时要注意。有结构的sizeof哪里(无效*)!=的sizeof(int)的,例如LP64。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top