【问题标题】:C++ is static typed language, why can we get type at runtimeC++是静态类型语言,为什么我们可以在运行时获取类型
【发布时间】:2013-09-24 17:18:50
【问题描述】:
TYPE& dynamic_cast<TYPE&> (object);
TYPE* dynamic_cast<TYPE*> (object);

例如我们可以得到这样的类型。 C++是静态类型语言,为什么我们可以在运行时获取类型

【问题讨论】:

  • 每个对象都有一个静态类型(在编译时已知)和一个动态类型(它实际上在运行)。在处理类层次结构时,静态类型和动态类型通常不同。
  • 对“为什么”的简短回答是:“因为在某些情况下这样做很有用。”
  • 您的意思是“为什么我们不能在运行时获取类型”?

标签: c++ types static-typing


【解决方案1】:
C++ 中的

变量 具有静态确定的类型。 对象不一定。您只需要通过静态已知类型的变量来处理对象。

例子:

int * p = new int[argc];   // there is an object whose dynamic type is int[argc]

Base * p = new Derived;    // *p has dynamic type Derived

Base * q = rand() % 2 ? new Derived1 : new Derived2;    // ???

【讨论】:

  • 郑重声明,我个人不同意“对象”的这个定义。对象具有静态类型,但表达式(例如 *p)可能没有。
  • @BenjaminLindley 在规范中,表达式具有静态类型,对象具有动态类型。动态类型是表达式引用的对象的最派生对象的类型,静态类型是不包括执行语义的程序分析产生的表达式的类型。见 1.3.7 和 1.3.23。
  • @bames53:我在读它,你似乎从中得到的意思并不是我从中得到的意思。 1.3.23 表示表达式具有静态类型(*p 的静态类型始终为Base&amp;)。 1.3.7 是说表达式也有动态类型(在这种情况下,*p 的动态类型是Derived&amp;,但可能会改变),而不是对象具有动态类型。
  • @BenjaminLindley:new T[N] 肯定会创建一个array-of-N-T,这是一种类型,它不是静态确定的,不是吗?
  • 在这里使用“静态类型”的意义(即类型在编译时已知),对象肯定没有静态类型。然而,还有另一种意义:一个对象一旦被构造就永远不会改变它的类型,从这个意义上说,类型是静态的。
【解决方案2】:

C++ 是一种静态类型语言。这意味着您不能在运行时创建新的类/类型声明并实例化它的对象/变量,这在 Javascript 或 PHP 中是可能的。

dynamic_castRTTI 的一部分,C++ 尝试在运行时提供类型信息。当你通过dynamic_cast 投射一个对象时,你并没有创建新类型,你只是在做一个多态的事情。

但是,您可以说 C++ 既是静态类型又是动态类型。

【讨论】:

  • C++ 是静态类型的,因为变量的类型是在编译时声明的。在此处使用的意义上,这与您无法在运行时创建新类型这一事实无关(尽管这是可以赋予​​表达式的另一种合理含义)。
【解决方案3】:

虽然评论(说对象具有静态类型)和答案(说变量具有静态类型,但对象不一定)之间似乎存在一些分歧,但我想我会投入两分钱主题。

在 C++ 中,变量 对象都具有静态类型。当您创建一个对象(例如,无论是全局的、本地的还是使用 new 创建的)时,您必须给出其类型的静态规范。

同样,当您创建变量时,它始终具有静态类型。例如,T *xTprime &amp;y 分别将x 定义为指向T 的指针,将y 定义为对TPrime 的引用。

事情变得动态的一个地方是,指针或引用不仅可以引用为其定义的静态类型,而且可以引用从该类型派生的任何其他类型。 “指向T 的指针”类型的变量实际上是“指向T 的指针或T 的任何衍生物”类型的变量(同样带有引用)。

因此,给定一个类型为 T 的变量(指针|引用)引用某个对象,指针本身和它所引用的对象都具有静态类型——但它们不一定是相同的 静态类型。

dynamic_cast 允许您确定引用对象的静态类型,即使/如果它是/可能与用于引用对象的指针/引用的静态类型不同。 dynamic_cast 还允许您确定一个中间类型,它不是指针的真正静态类型它所引用的对象,如果继承层次结构包括一些中间在两者之间键入。例如,给定:

struct base {
    virtual ~base() {}
};

struct intermediate : base {};

struct derived : intermediate {};

...我们可以有类似的东西:

base *b = new derived;
intermediate *i = dynamic_cast<intermediate *>(b);

...演员会成功。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-26
    • 2011-02-11
    • 1970-01-01
    • 2016-03-31
    • 2015-11-03
    • 2023-02-23
    相关资源
    最近更新 更多