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

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

1.3.3 - Тип наиболее производного объекта (1.8), к которому относится lvalue, обозначенное выражением lvalue. [Пример: если указатель (8.3.1) p, статическим типом которого является «указатель на класс 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;
}

person user103214    schedule 04.10.2011    source источник


Ответы (4)


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

Неа.

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

То есть, если у нас есть:

class A {

};

class B : public A { };


B l;
A& k = l;

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

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

person Klaim    schedule 04.10.2011
comment
+1, но я думаю, вы могли бы сделать этот пример еще более понятным, добавив пример, в котором new вообще не используется. - person San Jacinto; 04.10.2011
comment
Не хватит A &k = B();? - person arne; 04.10.2011
comment
В моем примере у меня есть виртуальные функции, что означает, что вызовы будут разрешаться во время выполнения. как здесь применяется динамика, когда нет динамической привязки? - person user103214; 04.10.2011
comment
@ user974191 Вы имеете в виду, как реализовано наследование? Может быть, поискать виртуальный стол. В вашем примере динамический тип, известный во время выполнения, очевидно, является производным. Однако в некотором коде вы можете работать с базовым типом, который на самом деле является чем-то другим, без необходимости знать. - person Klaim; 04.10.2011
comment
@arne Вы используете неконстантную ссылку с временным. Это даже не компилируется. Если я правильно помню, это было бы со ссылкой на константу. - person Klaim; 05.10.2011

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

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

person eran    schedule 04.10.2011
comment
Но *p - это не переменная, это выражение. - person curiousguy; 30.06.2019

В статически типизированном языке, таком как, например, 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 тип 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 из b может быть Base или Derived.

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

person Matthieu M.    schedule 04.10.2011

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

person aj8080    schedule 04.10.2011