两个dynamic_cast问题

Two dynamic_cast questions

本文关键字:问题 cast dynamic 两个      更新时间:2023-10-16
  1. 您会在频繁运行的方法中使用动态强制转换吗?它有吗一大笔开销?

  2. dynamic_cast返回的指针究竟是什么。指向同一地址的指针?指向不同实例的指针?我缺乏这种理解。更具体-只有在运行时,我才希望对父类型的指针进行赋值结果是一个指向子类型的指针。解决方案?

谢谢。

dynamic_cast可帮助您在执行下广播时检查有效性。

如果指针或引用不能安全地向下转换,则返回NULL或抛出异常(引用为std::bad_cast)。

您会在频繁运行的方法中使用动态强制转换吗?它有很大的开销吗 CCD_ 3确实使用一些附加的CCD_。所以肯定会有开销。通常,指向typetypeinfo的指针将被添加到virtual table。我通常这样说,因为虚拟机制本身是依赖于编译器实现的细节(不同的编译器可能会有所不同)。

您必须使用一些好的评测工具来评测代码,以确定重复调用dynamic_cast是否会降低代码的性能。

dynamic_cast返回的指针究竟是什么。指向同一地址的指针?指向不同实例的指针

当我们不使用dynamic_cast分析下向广播,而是分析上向广播时,更容易理解。给定类型base和从base继承的另一个类型derivedderived类型将包含类型base的子对象。当指向derived对象的指针向上投射到指向base的指针时,操作的结果将是derived内部的base子对象的地址。执行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;
}

程序将打印truefalse。请注意,如果要比较void*,则必须显式转换其中一个指针,否则编译器将对下转换的指针执行隐式上转换。

方法是否"频繁运行"并不重要,只有在运行它对所需性能产生重要负面影响时才重要。找到答案的唯一方法就是对代码进行概要分析。

返回的指针只是一个指针。您需要发布示例代码来澄清问题的后半部分。如果你的意思是:

Base * p1 = ....;
Derived * d = dynamic_cast<Derived*>(p1);
if ( d ) {
     (*d) = "foobar";
}

如果Derived支持赋值,那就可以了。

您会在频繁运行的方法中使用动态强制转换吗?它有很大的开销吗?

它没有太大的开销。但这取决于编译器对RTTI的实现。但是,不要过早地进行优化。

dynamic_cast返回的指针究竟是什么。指向同一地址的指针?指向不同实例的指针?我缺乏这种理解。更具体地说,只有在运行时它是指向子类型的指针时,我才希望对父类型的指针进行赋值。解决方案?

派生类的任何对象都包含其基类的opjects。dynamic_cast返回指向其中一个对象的指针(当类只继承一个基类时,它通常是同一指针,但如果类继承了多个基类,它就不是同一指针)。但这取决于使用的编译器。

  1. 请参阅这篇文章的公认答案如何在linux上评测我的C++应用程序。它涵盖了调用valgrind的选项,以及在一个漂亮的gui中查看概要文件结果的应用程序。

  2. 动态强制转换将返回一个与参数地址相同的类型的指针,因此它指向相同的对象。当将"son"类型动态转换为"father"类型时,如果参数不是"son"型,则动态转换将抛出std::bad_cast异常。

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将返回一个非null指针。如果指向的对象不是目标类的实例,则返回一个空指针。

注:输入到dynamic_cast的指针所指向的确切内存位置和dynamic_cast返回的指针可能不相同。示例:假设ChildA继承自两个类,Base和SomeInterface。可以将ChildA指针静态化为Base指针和SomeInterface指针。这两个父类指针中至少有一个不会指向与ChildA指针相同的内存位置。动态强制转换这两个父类指针中的任何一个都将返回原始ChildA指针。