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

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

谢谢你。

4

5 回答 5

6

dynamic_cast帮助您在执行向下转换时检查有效性。

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

您会在频繁运行的方法中使用动态转换吗?它有很大的开销吗? dynamic_cast确实使用了一些额外RTTI(Run Time Type Information)的东西来确定演员表的有效性。所以肯定会有开销。通常,指向 的指针typeinfotype添加到virtual table. 我通常说,因为虚拟机制本身是依赖于编译器实现的细节(可能因不同的编译器而异)。

您将不得不使用一些好的分析工具来分析您的代码,以确定dynamic_cast重复调用是否会降低代码的性能。

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

当我们分析upcasting而不是分析downcasting时,更容易理解。给定一个类型和另一个继承自的类型,该类型将包含一个 type 的子对象。当指向对象的指针向上转换为指向的指针时,操作的结果将是内部子对象的地址。执行 a会恢复该操作,并返回一个指向包含作为参数传递的地址中的子对象的对象的指针(做同样的事情,但它将应用可能的偏移量而不实际检查运行时类型)。dynamic_castbasederivedbasederivedbasederivedbasebase deriveddynamic_castderivedbasestatic_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, false。请注意,void*如果要比较它们,则必须显式转换其中一个指针,否则编译器将对向下转换的指针执行隐式向上转换。

于 2011-06-15T07:41:28.850 回答
1

该方法是否“经常运行”并不重要,只要运行它对所需性能有重要的负面影响。找出这一点的唯一方法是分析您的代码。

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

Base * p1 = ....;

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

如果 Derived 支持分配,那很好。

于 2011-06-15T07:41:43.683 回答
1

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

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

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

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

于 2011-06-15T07:54:09.827 回答
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。您可以将 ChildA 指针静态转换为 Base 指针和 SomeInterface 指针。这两个父类指针中的至少一个不会指向与 ChildA 指针相同的内存位置。动态转换这两个父类指针中的任何一个都将返回原始 ChildA 指针。

于 2011-06-15T08:27:16.473 回答
0
  1. 请参阅这篇文章How to profile my C++ application on linux的公认答案。它涵盖了调用 valgrind 的选项以及查看配置文件结果的应用程序的良好 gui。

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

于 2011-06-15T07:45:05.063 回答