Что такое динамический тип объекта - PullRequest
10 голосов
/ 04 октября 2011

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

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

Также, что означает следующая цитата

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

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

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

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

Ответы [ 4 ]

23 голосов
/ 04 октября 2011

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

Нет.

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

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

class A {

};

class B : public A { };


B l;
A& k = l;

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

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

5 голосов
/ 04 октября 2011

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

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

3 голосов
/ 04 октября 2011

В статически типизированном языке, таком как, например, 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 baseBase и derived - это Derived.
  • В методе print тип static для b равен Base (всегда)
  • В зависимости отчисло аргументов, dynamic из b равно Base или Derived

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

0 голосов
/ 04 октября 2011

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

...