您是否会在频繁运行的方法中使用动态强制转换?它有吗? 开销很大?
dynamic_cast返回的指针究竟是什么?指向同一地址的指针? 指向不同实例的指针?我缺乏这种理解。更具体 - 我希望只有在运行时才能对父类型的指针进行赋值 原来是一个儿子类型的指针。溶液
谢谢。
答案 0 :(得分:6)
dynamic_cast
可帮助您在执行向下转换时检查有效性。
如果无法安全地下载指针或引用,则返回NULL或引发异常(std::bad_cast
为引用)。
您是否会在频繁运行的方法中使用动态强制转换?是否有很大的开销?
dynamic_cast
确实使用了一些额外的RTTI(Run Time Type Information)
来确定演员表的有效性。所以肯定有一个开销。通常,typeinfo
的{{1}}指针将添加到type
。我通常说,因为虚拟机制本身是编译器实现依赖的细节(可能因不同的编译器而异)。
您必须使用一些好的分析工具来分析您的代码,以确定调用virtual table
是否会反复降低代码的性能。
dynamic_cast
返回的指针究竟是什么?指向同一地址的指针?指向不同实例的指针?
我们更容易理解,而不是使用dynamic_cast
分析向下转换,我们会分析向上转播。如果类型为dynamic_cast
,而另一种类型base
继承自derived
,则base
类型将包含类型为derived
的子对象。当指向base
对象的指针被上传到指向derived
的指针时,操作的结果将是base
子对象里面的地址 {{ 1}}。执行base
恢复该操作,并返回一个指向derived
对象的指针,该对象在作为参数传递的地址中包含dynamic_cast
子对象(derived
也是如此,但它将应用可能的偏移量而不实际检查运行时类型。)
在最简单的情况下,使用单个(非虚拟)继承,base
子对象将对齐static_cast
,但在多重继承的情况下,情况并非如此:
derived
该程序将打印base
,struct base {
int x;
virtual void foo() {}
};
struct another_base {
virtual void bar() {}
};
struct derived : base, another_base {};
int main() {
derived d;
base * b = &d; // points to the base subobject inside derived
another_base * o = &d; // points to the another_base subobject inside derived
std::cout << std::boolalpha
<< ( static_cast<void*>(b) == dynamic_cast<derived*>(b) ) << "\n"
<< ( static_cast<void*>(o) == dynamic_cast<derived*>(o) ) << std::endl;
}
。请注意,如果要比较它们,则必须显式地将其中一个指针转换为true
,否则编译器将执行 downcasted 指针的隐式向上转换。
答案 1 :(得分:1)
如果方法“频繁运行”并不重要,只有在运行它对所需性能产生重要的负面影响时才会这样。找到它的唯一方法是分析你的代码。
返回的指针只是一个指针。您需要发布示例代码以澄清问题的后半部分。如果你的意思是:
Base * p1 = ....;
Derived * d = dynamic_cast<Derived*>(p1);
if ( d ) {
(*d) = "foobar";
}
如果Derived支持赋值,那就很好了。
答案 2 :(得分:1)
您是否会在频繁运行的方法中使用动态强制转换?它有很大的开销吗?
它没有太大的开销。但这取决于编译器的RTTI实现。但是,不要过早优化。
dynamic_cast返回的指针究竟是什么?指向同一地址的指针?指向不同实例的指针?我缺乏这种理解。更具体 - 只有在运行时它被证明是一个指向子类型的指针时,我希望对父类型的指针进行赋值。溶液
派生类的任何对象都包含其基类的对象。 dynamic_cast返回指向其中一个对象的指针(当类只继承一个基类时,它通常是相同的指针,但如果类继承多于1个基类,则它不是相同的指针)。但这取决于使用过的编译器。
答案 3 :(得分:0)
查看此帖How to profile my C++ application on linux的已接受答案。它涵盖了调用valgrind的选项以及用于查看配置文件结果的应用程序。
动态强制转换将返回您使用与参数相同的地址转换的类型的指针,因此它指向同一个对象。当动态将“son”类型转换为“父类型”时,如果参数不是“son”类型,则动态转换将抛出std :: bad_cast异常。
答案 4 :(得分:0)
dynamic_cast返回的指针究竟是什么?指向同一地址的指针?指向不同实例的指针?我缺乏这种理解。更具体 - 我希望对父类型的指针进行赋值,只有在运行时它才会成为指向子类型的指针。
假设你有
class Base { ... };
class ChildA : public Base { ... };
class ChildB : public Base { ... };
ChildA childa;
ChildB childb;
Base * ptra = &childa;
Base * ptrb = &childb;
ChildA * ptra_as_ChildA = dynamic_cast<ChildA*>(ptra); // == &childa
ChildA * ptrb_as_ChildA = dynamic_cast<ChildA*>(ptrb); // == NULL
如果指向对象是目标类的实例或从目标类派生的类,则dynamic_cast将返回非空指针。如果指向的对象不是目标类的实例,则返回空指针。
注意:输入到dynamic_cast的指针指向的确切内存位置和dynamic_cast返回的指针可能不一样。示例:假设ChildA继承自两个类,Base和SomeInterface。您可以static_cast一个指向Base指针和SomeInterface指针的ChildA指针。这两个父类指针中的至少一个不会指向与ChildA指针相同的内存位置。动态转换这两个父类指针中的任何一个都会返回原始的ChildA指针。