我正在阅读有关dynamic_cast的信息,然后我遇到了以下声明(from cplusplus.com):
兼容性说明:此类型的dynamic_cast需要运行时类型 用于跟踪动态类型的信息(RTTI)。一些编译器 支持此功能作为默认禁用的选项。这个 需要使用dynamic_cast来启用运行时类型检查 适当地使用这些类型。
示例后:
// dynamic_cast
#include <iostream>
#include <exception>
using namespace std;
class Base { virtual void dummy() {} };
class Derived: public Base { int a; };
int main () {
try {
Base * pba = new Derived;
Base * pbb = new Base;
Derived * pd;
pd = dynamic_cast<Derived*>(pba);
if (pd==0) cout << "Null pointer on first type-cast.\n";
pd = dynamic_cast<Derived*>(pbb);
if (pd==0) cout << "Null pointer on second type-cast.\n";
} catch (exception& e) {cout << "Exception: " << e.what();}
return 0;
}
作者的意思是&#34;这种类型的dynamic_cast&#34;?是不是dynamic_cast只用于多态类(差不多)?并且他提到这个RTTI是动态转换工作所需要的东西,这是否意味着你必须谨慎使用dynamic_cast,因为你不知道它是否被编译器完全支持,因此比其他的转换风险更大那些不需要这个RTTI的运营商?
答案 0 :(得分:3)
兼容性说明涉及前一段(和代码示例):
但是
dynamic_cast
也可以向下转换(从指针到基础转换为指向派生的)多态类(具有虚拟成员的类),如果 - 并且只有 - 指向object是目标类型的有效完整对象。
这是真的:向下转换需要一个多态类型的对象,RTTI在运行时遍历对象的继承树。
其他类型的dynamic_cast
在之前的段落中解释:
这自然包括指针upcast (从指针到派生转换为指针到base),与隐式转换允许的方式相同。 / p>
此处不需要RTTI,因为对象的基础始终是静态已知的。
因此,您只需要完整阅读周围的文字,以便了解您正在阅读的文字的背景。
但是,我会注意到,根据我的经验,默认情况下禁用RTTI的编译器基本上是闻所未闻的。我并不是说不存在 - 可能有一些针对嵌入式平台的针对特定行业的特定编译器,这样做可以将程序员在Makefile中保存几个字节。但是大多数人使用的编译器(GCC,Clang,Visual Studio,ICC,Comeau)都是我所知道的,将RTTI作为标准打包并保留,直到你要求关闭它为止。
答案 1 :(得分:0)
您提到的部分中的作者提到了使用dynamic_cast
多态类型时的情况:当您编写类似dynamic_cast<X*>(p)
的内容时更准确一些。
在这种情况下,您将需要运行时类型信息,以便可以使用dynamic_cast
(请参阅下面的示例)。
您可以使用上面提到的编译器选项-fno-rtti
使编译器禁止生成有关具有虚函数的每个类的此类信息,但很少推荐。
“其他”案例涉及dynamic_cast
对void*
的使用情况。
例如,请考虑以下代码:
class A {
public:
virtual ~A() = default;
};
class B : public A {};
int main()
{
A *p = new B();
void *pv = dynamic_cast<void*>(p);
//B *pb = dynamic_cast<B*>(p);
delete p;
return 0;
}
如果用g++ test.cpp -std=c++11 -fno-rtti
编译代码,那就没关系了。但是,如果在取消注释B *pb = dynamic_cast<B*>(p);
后执行相同操作,编译器将为此特定行提供以下错误消息:错误:-fno-rtti 不允许使用'dynamic_cast'。请注意,即使使用void*
(已手动或默认设置),投射到-fno-rtti
仍然有效。
答案 2 :(得分:-1)
rtti
在运行时很昂贵,一些嵌入式系统使用标志进行编译,禁用它。它给你的全部是dynamic_cast
和typeid
。
因此,我解释
因为您不知道编译器是否完全支持它
as
因为您的代码可能已使用rtti禁用编译。