Что такое динамический тип объекта

Я думаю, что динамический тип означает динамически выделенный объект с помощью new. В следующем случае, скажем, p указывает на динамический тип или статический тип объекта? В стандарте он не говорит о динамическом типе, являющемся динамическим объектом.

1.3.3 - Тип самого производного объекта (1.8), которому обозначается lvalue по выражению lvalue. [Пример: если указатель (8.3.1) p static type - "указатель на класс B" указывает на объект класса D, полученный из B (раздел 10), динамический тип выражения * p является "D." Ссылки (8.3.2) рассматриваются аналогично. ]

И что означает следующая цитата

Динамическим типом выражения rvalue является его статический тип

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

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

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

Ответ 1

Я думаю, что динамический тип означает динамически выделенный объект используя новый.

Неа.

Динамический тип - это реальный тип объекта, к которому можно обратиться через ссылку (включая указатель), указывающую на базовый тип своего реального типа.

То есть, если мы имеем:

class A {

};

class B : public A { };


B l;
A& k = l;

Здесь k - ссылка на объект типа A, но реальный тип упомянутого объекта, его динамический тип, равен B.

Здесь "динамический" имеет значение "известно только во время выполнения".

Ответ 2

Статический тип - это тип переменной, который является единственным типом, известным в время компиляции (поэтому считается статическим - не может измениться). Динамический тип - это тип объекта, который на самом деле указывает на время выполнения. Dynamic здесь означает, что он известен только во время выполнения, что означает, что он может измениться (а именно, одна переменная может указывать на различные объекты разных типов).

Использование new в этом контенте не имеет значения, как показывает ваш собственный пример. В основном, статический и динамический тип d равен Derived, потому что это не указатель или ссылка. p, однако, имеет статический тип Base, но в вашем коде динамический тип будет Derived.

Ответ 3

В статически типизированном языке, например, на С++ или 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 тип static b равен Base const&. Поэтому компилятор проверяет, что все вызванные методы существуют в контексте объекта Base.

Однако при выполнении вызова вызов name, поскольку этот метод является виртуальным, выполняется в отношении типа объекта dynamic:

  • это может быть Base
  • это может быть Derived
  • это может быть другой производный класс из Base, который мы еще не знаем

Поэтому в следующем примере:

int main(int argc, char* argv[]) {
  if (argc == 1) {
    Base base;
    print();
  } else {
    Derived derived;
    print(derived);
  }
};
  • Тип static и dynamic Base равен Base, а Derived - Derived.
  • В методе print тип static b равен Base (всегда)
  • В зависимости от количества аргументов dynamic of b имеет значение Base или Derived

Это текущая ошибка, предполагающая, что полиморфизм обязательно основан на распределении динамической памяти, но два понятия, хотя и не ортогональные, могут использоваться без друг друга в некоторых условиях.

Ответ 4

Динамическое распределение памяти всегда выполняется во время выполнения. Это может быть достигнуто с использованием ключевого слова "новое". но есть еще один случай, как упоминалось в вашей проблеме * p = & d здесь, поскольку вы сделали функцию базового класса "Виртуальная", она сообщает компилятору относиться к "p" этим Контентом, а не типом указателя, к которому он принадлежит .so это одно из распределения динамической памяти, поскольку компилятор никогда не знает, какой адрес объекта класса будет храниться во время выполнения, он знает только тип указателя (т.е. указатель базового класса или указатель производного класса).