【问题标题】:What is dynamic type of object什么是动态对象类型
【发布时间】:2011-10-04 14:40:33
【问题描述】:

我认为动态类型意味着使用new 动态分配的对象。在下面的情况下,你说p是指向动态类型还是静态类型的对象?在标准中,它并没有说动态类型是动态对象。

1.3.3 - 左值表示的最衍生对象 (1.8) 的类型 由左值表达式引用。 [示例:如果指针 (8.3.1) p 其 静态类型是“指向 B 类的指针”是指向类的对象 D,派生自 B(第 10 条),表达式 *p 的动态类型 是“D”。参考文献(8.3.2)的处理方式类似。 ]

下面的引用是什么意思

右值表达式的动态类型是它的静态类型

class Base {
    virtual void foo(){}
};

class Derived : public Base {
    void foo(){}
};

int main()
{
    Derived d;
    Base *p = &d;
}

【问题讨论】:

    标签: c++ pointers inheritance lvalue subobject


    【解决方案1】:

    我认为动态类型意味着动态分配的对象 使用新的。

    没有。

    动态类型是对象的真实类型,可以通过指向其真实类型的基类型的引用(包括指针)访问。

    也就是说,如果我们有:

    class A {
    
    };
    
    class B : public A { };
    
    
    B l;
    A& k = l;
    

    这里的 k 是对 A 类型对象的引用,但被引用对象的真实类型,即它的动态类型,是 B。

    这里的“动态”的意思是“只在运行时知道”。

    【讨论】:

    • +1,但我认为您可以通过添加一个根本不使用 new 的示例来使示例更加清晰。
    • A &k = B(); 不够吗?
    • 在我的示例中,我有虚函数,这意味着调用将在运行时解析。在没有动态绑定的情况下,动态在这里如何应用?
    • @user974191 你的意思是,继承是如何实现的?也许寻找“虚拟表”。在您的示例中,“动态类型”又名“运行时已知的真实类型”显然是派生的。但是,在某些代码中,您可以使用实际上是其他东西的 Base 类型,而无需知道。
    • @arne 您正在使用非常量引用和临时引用。那甚至不会编译。如果我没记错的话,它会带有一个 const 引用。
    【解决方案2】:

    静态类型是变量的类型,它是编译时唯一已知的类型(因此被认为是静态的 - 不能改变)。 动态类型 是实际指向运行时 的对象的类型。这里的动态意味着它只在运行时才知道,这意味着它可能会改变(即一个变量可以指向各种类型的各种对象)。

    正如您自己的示例所示,在此内容中使用 new 无关紧要。在你的主要,d 的静态和动态类型是Derived,因为它不是指针或引用。但是,p 的静态类型为 Base,但在您的代码中,动态类型为 Derived

    【讨论】:

    • 但是*p 不是一个变量,它是一个表达式。
    【解决方案3】:

    在静态类型语言(例如 C++ 或 Java)中,static 可能指的是编译时已知的信息,而dynamic 指的是运行时已知的信息。

    例如:

    struct Base { virtual std::string name() const { return "Base"; } };
    
    struct Derived: Base { std::string name() const { return "Derived"; } };
    
    void print(Base const& b) { std::cout << b.name() << "\n"; }
    

    print方法中,bstatic类型是Base const&amp;。因此,编译器会检查所有调用的方法是否存在于Base 对象的上下文中。

    然而,当执行来临时,对name的调用,因为该方法是虚拟的,是针对对象的dynamic类型执行的:

    • 这可能是Base
    • 这可能是Derived
    • 这可能是来自Base 的另一个我们还不知道的派生类

    因此,在下面的例子中:

    int main(int argc, char* argv[]) {
      if (argc == 1) {
        Base base;
        print();
      } else {
        Derived derived;
        print(derived);
      }
    };
    
    • basestaticdynamic 类型是 BasederivedDerived
    • print 方法中,bstatic 类型为Base(始终)
    • 根据参数的数量,bdynamicBaseDerived

    假设多态性必然基于动态内存分配是当前的错误,但这两个概念虽然不是正交的,但在某些情况下可以单独使用。

    【讨论】:

      【解决方案4】:

      动态内存分配总是在运行时完成。它可以使用“new”关键字来实现。 但是在您的问题 *p=&d 中提到了另一种情况,因为您已经将基类函数设为“虚拟”,它告诉编译器通过它的内容而不是它所属的指针类型来处理“p”。所以这是动态内存分配的一种,因为编译器永远不知道您在运行时要存储哪个类对象的地址,它只知道它是哪种类型的指针(即基类指针或派生类指针)。

      【讨论】:

        猜你喜欢
        • 2011-11-15
        • 1970-01-01
        • 2015-01-03
        • 1970-01-01
        • 2015-03-11
        • 2016-03-22
        • 1970-01-01
        • 1970-01-01
        • 2011-07-03
        相关资源
        最近更新 更多